lock变量应该声明为volatile吗?

时间:2012-07-17 12:58:44

标签: c# .net multithreading locking volatile

我有以下Lock声明:

private readonly object ownerLock_ = new object();

lock (ownerLock_)
{
}

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

private readonly volatile object ownerLock_ = new object();

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

来自MSDN

  

volatile修饰符通常用于访问的字段   多个线程,不使用lock语句来序列化访问。

2 个答案:

答案 0 :(得分:19)

如果您在您拥有锁时访问锁定“守卫”的数据,那么是 - 使这些字段变得多余是多余的。您也不需要使ownerLock_变量变为volatile。 (你目前没有在lock语句中显示任何实际代码,这使得很难用具体的术语来讨论 - 但我假设你实际正在阅读/修改lock语句中的一些数据。)

volatile应该非常在应用程序代码中很少使用。如果您想要对单个变量进行无锁访问,Interlocked几乎总是更容易理解。如果你想要无锁无限访问,我几乎总是会开始锁定。 (或者尝试使用不可变数据结构开始。)

我只希望在代码中看到volatile,它试图为线程构建更高级别的抽象 - 例如,在TPL代码库中。对于那些真正彻底了解.NET内存模型的专家来说,它真的是一个工具......对于那些人很少,IMO。

答案 1 :(得分:2)

如果某些内容是readonly,那么它是线程安全的,句号。 (好吧,差不多。专家可能能够弄清楚如何在lock语句中获取NullReferenceException,但这并不容易。)使用readonly你不需要volatileInterlocked或锁定。它是多线程的理想关键字,您应该尽可能地使用它。它对于一个锁定对象很有用,它的最大缺点(你不能改变它)并不重要。

此外,虽然引用是不可变的,但引用的对象可能不是。 “new object()”在这里,但如果它是List或其他可变的 - 而不是线程安全的 - 你想要锁定引用(以及所有其他引用它,如果有的话)保持对象不要同时在两个线程中更改。