👉 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 |
---|---|---|
可见性 | ✅ 有 | ✅ 有 |
原子性 | ❌ 没有 | ✅ 有 |
是否阻塞 | ❌ 非阻塞 | ✅ 阻塞(互斥锁) |
应用场景 | 状态标识、单例等 | 临界区保护、读写操作 |