22

我有以下 Lock 语句:

private readonly object ownerLock_ = new object();

lock (ownerLock_)
{
}

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

private readonly volatile object ownerLock_ = new object();

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

来自MSDN

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

4

2 回答 2

20

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

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

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

于 2012-07-17T13:02:42.140 回答
2

如果某些东西是readonly线程安全的,那就是句号。(嗯,差不多。专家可能会弄清楚如何在您的lock语句中获得 NullReferenceException,但这并不容易。)readonly您不需要volatile,Interlocked或锁定。它是多线程的理想关键字,您应该尽可能使用它。它适用于一个锁对象,它的大缺点(你不能改变值)并不重要。

此外,虽然引用是不可变的,但引用的对象可能不是。“新对象()”在这里,但如果它是一个List或其他可变的东西——而不是线程安全的——你想要锁定引用(以及对它的所有其他引用,如果有的话)以阻止对象一次更改两个线程。

于 2012-07-17T17:20:13.017 回答