我讀過很多比較易失性和鎖的文章。據我了解lock,保證只有一個執行緒可以使用鎖并并行運行關鍵代碼,并volatile禁用記憶體優化 - 所以它們是不可替代的。使用volatile不應該替換lock. 盡管大多數文章lock在展示volatile.
假設我有一個超級簡單的類:
class Foo
{
private bool bar;
private static readonly object barLock = new object();
public void ToggleBar()
{
lock (barLock)
{
bar = !bar;
}
}
public bool ReadBar()
{
lock (barLock)
{
return bar;
}
}
}
假設ToggleBar僅由執行緒 A 和ReadBar執行緒 B 使用。
lock防止兩個執行緒并行訪問變數。但也應該bar如此volatile?
在我讀過的大多數文章中,這是“推薦”的解決方案(也是 Interlocked 類),但據我了解,它并不能解決已解決的問題volatile- 即使鎖執行緒 B 可能會讀取舊值由于bar記憶體優化和快取,不是嗎?
在這種情況下不bar應該是volatile 除了嗎?lock
uj5u.com熱心網友回復:
運行時允許移動記憶體訪問以進行優化。如果有鎖,則在進入鎖之前或離開鎖之后可能不會移動記憶體訪問。另請參閱Eric Lippert 的這篇博文:
C# 編譯器、JIT 編譯器和 CPU 都可以進行優化,前提是當前執行緒無法檢測到優化。特別是,變數的讀取和寫入可以重新排序或完全消除,前提是當前執行緒無法觀察到這樣做。[...] 鎖引入了對這些優化的限制。特別是:在 lock 陳述句開始之前不能移動讀取,并且在 lock 陳述句結束之后不能移動寫入。
因此,例如在您的ToggleBar方法中,您可以確保在輸入方法后讀取 bar 變數,并在離開方法時寫入它。在您的ReadBar方法中,您可以確保每次呼叫該方法時都會讀取該條。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/450265.html
