👉 volatile :不穩定的
英[?v?l?ta?l] 美[?vɑ?l?tl]
- adj.
不穩定的;<計>易失的;易揮發的,易發散的;爆發性的,爆炸性的;易變的,無定性的,無常性的;短暫的,片刻的;活潑的,輕快的,無憂慮的;暴躁的;易引起的;易惡化的;可能急劇波動的;<古>迅速游移的; - n.
<罕>有翅動物;易揮發物;
🚀 簡介
volatile 是 Java 中的一個輕量級同步機制,主要用于線程之間的變量可見性和禁止指令重排序。它不是用來代替 synchronized 的,而是適用于特定場景下的輕量并發控制。
? 一、volatile 的兩個核心作用
功能 | 說明 |
---|---|
1. 可見性 | 一個線程對變量的修改,其他線程能夠立即看到。 |
2. 禁止指令重排序 | 保證寫操作的順序不會被 JVM 或 CPU 優化打亂(有利于實現安全發布)。 |
🔍 二、典型使用場景
1. 狀態標志變量(最典型)
場景: 控制線程的啟動/關閉狀態,線程輪詢判斷某個狀態是否更新。
class Worker extends Thread {private volatile boolean running = true;public void run() {while (running) {// do something}}public void shutdown() {running = false;}
}
? 使用 volatile,可確保 shutdown() 方法修改的 running 變量,對 run() 方法中立即可見。
2. 雙重檢查鎖(DCL,單例模式)
場景: 延遲初始化(懶漢式單例)時,避免指令重排帶來的空指針問題。
public class Singleton {private static volatile Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) { // 第一次檢查synchronized (Singleton.class) {if (instance == null) { // 第二次檢查instance = new Singleton(); // 可能指令重排序 → 需要 volatile}}}return instance;}
}
? volatile 防止 new Singleton() 的指令重排。
3. 輕量級發布-訂閱模型
比如:多線程間通信或事件通知機制,不需要完整同步,僅靠可見性傳播狀態。
class FlagManager {public volatile boolean updated = false;
}
線程 A 修改 updated = true,線程 B 輪詢即可及時感知變化。
4. 避免無效同步開銷
當你只是想讓一個變量對所有線程可見,又不希望使用 synchronized 帶來的上下文切換成本時,用 volatile 是性能更優的選擇。
🚫 三、不適合 volatile 的場景(易錯)
自增操作(++)不是原子操作,不適合 volatile
volatile int count = 0;public void add() {count++; // 非線程安全,count++ 實際包含:讀 → 改 → 寫
}
? 正確做法:使用 AtomicInteger 或 synchronized
🔁 四、volatile 和 synchronized 區別
特性 | volatile | synchronized |
---|---|---|
可見性 | ? 有 | ? 有 |
原子性 | ? 沒有 | ? 有 |
是否阻塞 | ? 非阻塞 | ? 阻塞(互斥鎖) |
應用場景 | 狀態標識、單例等 | 臨界區保護、讀寫操作 |