http://www.ibm.com/developerworks/cn/java/j-jtp06197.html 一文筆記
在java中,為了提高性能,線程一般把變量從內存中備份一個副本到寄存器。volatile 關鍵字意思是易失性,明確表示
一個變量是會被多線程訪問的,每個線程在每次讀取都要從內存讀取原始副本的值,而不是緩存在寄存器中的值。每次修改
都是把值寫回到內存中。
Java語言包含兩種內在的同步機制:同步塊(或方法)和 volatile 變量。
synchronized鎖提供了兩種主要特性:
互斥(mutual exclusion) 和
可見性(visibility)。互斥即一次只允許一個線程持有某個特定的鎖,因此可使用該特性實現對共享數據的協調訪問協議,這樣,一次就只有一個線程能夠使用該共享數據。可見性必須確保釋放鎖之前對共享數據做出的更改對于隨后獲得該鎖的另一個線程是可見的。 否則,線程看到的共享變量可能是修改前的值或不一致的值,引發嚴重問題。
volatile能夠實現上述可見性,因為線程每次都是讀取原始版本的值,前一個線程的修改對后續線程來說是可見的。但volatile不能確保互斥。
volatile適用的原則:
- 對變量的寫操作不依賴于當前值。
- 該變量沒有包含在具有其他變量的不變式中。
所以volatile不能用作計數器,因為計數器的自增是一個讀-增-寫的過程,不是原子操作,在volatile不確保互斥的情況下,結果不準確。
不變式的意思是一個需要不變的規律,如起始要小于等于結束。上述2點簡單來說:即變量真正獨立于其他變量和自己以前的值 , 在這些
情況下可以使用
volatile
代替
synchronized
來簡化代碼。
volatile由于不阻塞線程,在性能一般比synchronized表現更好。
適用volatile的幾個場景:
1、狀態標志 比如標示服務啟動或停止。
2、獨立觀察 定期 “發布” 觀察結果供程序內部使用,
3、
結合使用 volatile 和 synchronized 實現 “開銷較低的讀-寫鎖”
@ThreadSafe
public class CheesyCounter {
private volatile int value;
// 使用volatile實現可見性,開銷低
public int getValue() { return value; }
// 使用synchronized實現互斥
public synchronized int increment() {
return value++;
}
}
posted on 2011-04-08 16:28
liucs 閱讀(372)
評論(0) 編輯 收藏 所屬分類:
Java