我最近遇到了the following post on the Resharper website。这是双重检查锁定的讨论,并且有以下代码:双重锁定内存模型保证
public class Foo
{
private static volatile Foo instance;
private static readonly object padlock = new object();
public static Foo GetValue()
{
if (instance == null)
{
lock (padlock)
{
if (instance == null)
{
instance = new Foo();
instance.Init();
}
}
}
return instance;
}
private void Init()
{
...
}
}
经后使得声称
如果我们假设的init()是用于并初始化的方法状态 美孚,然后上述代码可能无法按预期方式运行,由于 内存模型不保证读取和写入的顺序。作为 结果,对Init()的调用实际上可能在变量 实例处于一致状态之前发生。
这里是我的问题:
这是我的理解是.NET的内存模型(自2.0至少)有不要求
instance
声明为volatile
,因为lock
将提供全记忆围栏。情况不是这样,还是我误解了?是不是读取/写入重新排序只能观察多个线程?这是我的理解,在一个单一的线程,副作用将是一致的顺序,并且
lock
就位会阻止任何其他线程观察到的东西是不对的。我是否也在这里?
你对.NET 2.0内存模型是正确的。你不需要'易变'(因为它几乎不会达到你期望的效果),而'锁'的确可以做到完全的篱笆。但是,正如Chibacity指出的那样,当谈到线程安全性时,很容易忽略竞争条件。 – Steven