1.volatile最適用一個線程寫,多個線程讀的場合。
如果有多個線程並發寫操作,仍然需要使用鎖或者線程安全的容器或者原子變量來代替。(摘自Netty權威指南)
疑問:如果只是賦值的原子操作,是否可以多個線程寫?(答案:可以,但是一般沒有這樣的必要,即沒有這樣的應用場景)
最經典的使用案例:
volatile boolean shutdownRequested; ... public void shutdown() { shutdownRequested = true; } public void doWork() { while (!shutdownRequested) { // do stuff } }
使用場景2:
結合使用 volatile 和 synchronized 實現 “開銷較低的讀-寫鎖”
volatile 允許多個線程執行讀操作,因此當使用 volatile 保證讀代碼路徑時,要比使用鎖執行全部代碼路徑獲得更高的共享度 —— 就像讀-寫操作一樣。
public class CheesyCounter { private volatile int value; public int getValue() { return value; } public synchronized int increment() { return value++; } }
或者
private volatile long start = System.currentTimeMillis(); public synchronized long get() { return start++; }
正確使用 volatile 變量的條件
您只能在有限的一些情形下使用 volatile 變量替代鎖。要使 volatile 變量提供理想的線程安全,必須同時滿足下面兩個條件:
- 對變量的寫操作不依賴於當前值。
- 該變量沒有包含在具有其他變量的不變式中。
更多使用場景可參考:
http://www.ibm.com/developerworks/cn/java/j-jtp06197.html