JVM 允許執行緒將共享變數快取於本地記憶體(暫存器/L1 Cache),導致「寫入執行緒更新主存,讀取執行緒仍讀到舊值」的可見性問題。volatile 強制:
從而確保任意時刻所有執行緒看到的值一致。
volatile 變數的寫入,對後續讀取該變數的執行緒必定可見(happens-before)。volatile 讀寫與普通讀寫重排序,保證程式順序語意。volatile long/double 讀寫非原子(32 位拆兩次),其餘基本型別原子;複合操作(i++、check-then-act)不保證原子,仍需 synchronized 或 Atomic*。volatile boolean shutdown = false;volatile Config config = null;(雙重檢查鎖定模式中必要)。synchronized 區塊內的變數(鎖已提供可見性)。final 已隱含可見性)。volatile 會阻擋 JIT 某些優化(如暫存器分配、指令重排),並觸發記憶體屏障指令。單次存取開銷約為普通讀寫的 2–3 倍,但遠低於鎖。高頻熱點路徑建議改用 AtomicLong 等無鎖結構。
class ConfigManager {
private volatile Config current; // 發布時寫入 volatile
public Config getConfig() { return current; } // 讀取無需同步
public void reload(Config newCfg) { current = newCfg; }
}
volatile 是「輕量級同步」利器,專解決可見性與有序性,不解決原子性。正確使用前提:寫入不依賴舊值、讀寫無不變條件關聯。