我有以下Lock声明:
private readonly object ownerLock_ = new object();
lock (ownerLock_)
{
}
我应该使用volatile关键字作为我的锁定变量吗?
private readonly volatile object ownerLock_ = new object();
在MSDN上我看到它通常用于无锁定访问的字段,所以如果我使用Lock我不需要使用volatile?
来自MSDN:
volatile修饰符通常用于访问的字段 多个线程,不使用lock语句来序列化访问。
答案 0 :(得分:19)
如果您只在您拥有锁时访问锁定“守卫”的数据,那么是 - 使这些字段变得多余是多余的。您也不需要使ownerLock_
变量变为volatile。 (你目前没有在lock
语句中显示任何实际代码,这使得很难用具体的术语来讨论 - 但我假设你实际正在阅读/修改lock
语句中的一些数据。)
volatile
应该非常在应用程序代码中很少使用。如果您想要对单个变量进行无锁访问,Interlocked
几乎总是更容易理解。如果你想要无锁无限访问,我几乎总是会开始锁定。 (或者尝试使用不可变数据结构开始。)
我只希望在代码中看到volatile
,它试图为线程构建更高级别的抽象 - 例如,在TPL代码库中。对于那些真正彻底了解.NET内存模型的专家来说,它真的是一个工具......对于那些人很少,IMO。
答案 1 :(得分:2)
如果某些内容是readonly
,那么它是线程安全的,句号。 (好吧,差不多。专家可能能够弄清楚如何在lock
语句中获取NullReferenceException,但这并不容易。)使用readonly
你不需要volatile
,Interlocked
或锁定。它是多线程的理想关键字,您应该尽可能地使用它。它对于一个锁定对象很有用,它的最大缺点(你不能改变它)并不重要。
此外,虽然引用是不可变的,但引用的对象可能不是。 “new object()”在这里,但如果它是List
或其他可变的 - 而不是线程安全的 - 你将想要锁定引用(以及所有其他引用它,如果有的话)保持对象不要同时在两个线程中更改。