2012-07-17 138 views
19

我有以下锁声明:应该声明一个锁定变量是否为volatile?

private readonly object ownerLock_ = new object(); 

lock (ownerLock_) 
{ 
} 

我应该使用volatile关键字为我的锁变量?

private readonly volatile object ownerLock_ = new object(); 

在MSDN上,我看到它通常用于无锁定访问的字段,所以如果我使用锁定,我不需要使用易失性?

MSDN

挥发性改性剂通常被用于由 多个线程,而不使用锁定语句来串行访问访问的字段。

+0

我们需要更多的上下文来回答这个问题。与使用锁的对象相关的锁存在哪里? – 2012-07-17 13:00:35

+3

它当前存在的线程绝对是安全的。当您在锁定块中添加代码时,无法保证。 – 2012-07-17 13:00:55

+0

你不应该需要锁定只读对象,因为它是只读的... – NominSim 2012-07-17 13:01:16

回答

18

如果你只有史以来访问数据的锁“卫士”,而你自己的锁,然后是 - 使这些领域的挥发是多余的。您不需要使ownerLock_变量易变。 (您目前没有在lock声明中显示任何实际代码,这使得很难具体说明 - 但我假设您会实际上正在读取/修改lock声明中的某些数据。)

volatile应该是很少用在应用程序代码中。如果你想锁定一个变量,那么Interlocked几乎总是比较简单。如果你想要超越这个锁无锁访问,我几乎总是会开始锁定。 (或尝试使用不可变的数据结构来开始。)

我只希望在代码中看到volatile,该代码正尝试为线程构建更高级别的抽象 - 例如在TPL代码库中。这真的是一个专家的工具,它真的可以深入了解.NET内存模型...其中有很少的,IMO。

+0

感谢您的快速回复,可以说我只使用锁定,这似乎很少见,但是可以使用2个锁定语句的线程同时检查ownerLock_状态并尝试锁定它或彼此?我问这个问题是因为我的代码中存在锁定问题,我认为它与此问题有关。 – 2012-07-17 13:13:27

+0

@DorCohen:一次只有其中一人获得锁定。然后它将执行'lock'语句的主体,当它释放锁时,另一个线程将能够获取锁并执行代码。 – 2012-07-17 13:15:17

+0

@DorCohen,你的问题似乎不在于你锁定的内容,而是你想要在锁体内做什么。 – 2012-07-17 13:16:12

2

如果是readonly它是线程安全的,句号。 (嗯,差不多可能能够弄清楚如何在你的lock声明中得到一个NullReferenceException,但这并不容易。)使用readonly你不需要volatile,Interlocked或锁定。这是多线程的理想关键字,您应该尽可能使用它。对于一个锁定对象来说它很有用,因为它有很大的缺点(你不能改变这个值)并不重要。

此外,虽然参考是不可变的,但引用的对象可能不是。 “新对象()”在这里,但如果它是List或其他可变的 - 而不是线程安全的 - 想要锁定引用(以及所有其他引用,如果有的话)以保持该对象一次改变两个线程。

相关问题