Java Concurrency in Practice 聲明如下:當(dāng)線程 A 執(zhí)行一個同步塊,隨后線程 B 進(jìn)入一個由同一個鎖保護(hù)的同步塊時,在釋放鎖之前對A 可見的變量值保證在獲取鎖時對 B 可見。換句話說,當(dāng) B 執(zhí)行由同一鎖保護(hù)的同步塊時,A 在同步塊中或之前所做的一切對 B 都是可見的。沒有同步,就沒有這樣的保證。同樣的邏輯適用于 volatile 變量:volatile 變量的可見性影響超出了 volatile 變量本身的值。當(dāng)線程 A 寫入一個 volatile 變量,隨后線程 B 讀取同一個變量時,在寫入 volatile 變量之前對 A 可見的所有變量的值在讀取該 volatile 變量后對 B 可見。從描述中可以清楚地看出,當(dāng)您需要訪問某些共享狀態(tài)時,您可以使用這種可見性效果來實際替換(或限制使用)傳統(tǒng)鎖。在圖中的示例中,您可以看到線程 B 可以安全地讀取變量y,即使它在同步塊外的線程 A 中發(fā)生了更改。因此,當(dāng)您在線程上鎖定之前更改某些共享狀態(tài)時使用它是否安全visibility guarantee,然后獲取鎖定,做某事(或者什么都不做,我猜),釋放鎖然后在另一個線程中獲得相同的鎖鎖定,釋放它,然后安全地從第一個線程中更新的共享變量中讀取最新值?
2 回答

揚(yáng)帆大魚
TA貢獻(xiàn)1799條經(jīng)驗 獲得超9個贊
引用語句中有一個關(guān)鍵部分:
volatile 變量的可見性影響超出了 volatile 變量本身的值。當(dāng)線程 A 寫入一個 volatile 變量,隨后線程 B 讀取同一個變量時,在寫入 volatile 變量之前對 A 可見的所有變量的值在讀取 volatile 變量后對 B 可見。
雖然這顯然是正確的,但您在這里得到了關(guān)于 A 寫先于 B 閱讀的條件。然而,如果不鎖定,就無法保證讀/寫的順序——這就是重點(diǎn)。
所以你不能用 volatiles 替換每個同步,因為它不會產(chǎn)生相同的結(jié)果。

白板的微信
TA貢獻(xiàn)1883條經(jīng)驗 獲得超3個贊
是的,您可以visibility guarantee
通過使用或任一形式的鎖定以描述的方式獲得,但volatile
僅此而已。具體來說,您不會獲得相互訪問和原子性。synchronized
另請參閱 JLS中有關(guān) JVM的內(nèi)存模型和happens-before關(guān)系的部分,以獲得更多細(xì)節(jié)和深度。
添加回答
舉報
0/150
提交
取消