我最近遇到了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