我不明白爲什麼在這個實現stopped
不是volatile
- 如果一個不同的線程更新它會正確地反映?優雅地關閉工作線程
其次是測試(!Stopping
)原子?
編輯
此代碼是從an article written by Jon Skeet。
我不明白爲什麼在這個實現stopped
不是volatile
- 如果一個不同的線程更新它會正確地反映?優雅地關閉工作線程
其次是測試(!Stopping
)原子?
編輯
此代碼是從an article written by Jon Skeet。
因爲它只能在lock
內訪問。 A lock
也行爲,以確保您看到最新的值。
重新原子性(和我假設你真的意思是在這裏同步?);它沒有任何可能;即使Stopping
已同步,但我們不能再相信該值是我們退出lock
後的最新值。因此,!Stopping
與Stopping
沒有更多或更少的同步。重要的是我們知道我們最近至少檢查過了。有一個邊緣情況下,我們檢查之後我們檢查標誌,但這很好:當我們檢查時,確實應該繼續。
我明白了嗎? 每次獲得鎖定寄存器都會被刷新並且永遠不會讀取陳舊值?換句話說,如果我在一個緊密的循環中獲得一個鎖,那麼我不需要易失性?自從? – 2009-12-18 17:07:07
只要所有**其他**線程只有在它們持有(相同)鎖定時才更新字段,那麼是的。如果其他線程在沒有獲得鎖的情況下更新字段*,則所有投注都將關閉。 – 2009-12-18 18:46:20
請參閱this entry on SO。它解釋了爲什麼鎖定比volatile更受歡迎。此代碼的
但是,這個例子不屬於鏈接條目中的「什麼是非常好的」類別嗎?沒有辦法設置停止或停止爲假,所以不會有任何競爭條件。 – Niki 2009-12-18 12:59:12
行爲是在C#語言規範的第3.10節中定義:
C#程序前進的執行,使得每個執行線程的副作用是在臨界執行點保存。副作用定義爲讀取或寫入易失性字段,寫入非易失性變量,寫入外部資源以及拋出異常。必須保留這些副作用順序的關鍵執行點是對易失性字段(第10.5.3節),鎖定語句(第8.12節)以及線程創建和終止的引用。
換句話說,鎖定語句足以保證避免需要聲明停止的字段volatile。
JIT編譯器如何實現此規則是一個有趣的問題,因爲鎖定語句僅調用Monitor.Enter()和Exit()方法。我不認爲它對這些方法有特別的瞭解,我認爲這是進入在Enter()調用之後開始的try塊的副作用。但這只是一個猜測。
我不明白,Jon Skeet如何描述這一點? – YOU 2009-12-18 12:13:56
@ S.Mark:它來自Jon Skeets關於關閉工作線程的頁面。 – 2009-12-18 12:20:25
@ S.Mark ...與編程有關的任何東西都與Jon Skeet有關......這應該是Jon Skeet的事實!http://meta.stackexchange.com/questions/9134/jon-skeet-facts – James 2009-12-18 12:55:38