概述
volatile 是 Java 中用于修饰变量的关键字,它提供了一种轻量级的线程间通信机制。与 synchronized 相比,volatile 不会引起线程上下文切换和调度,因此性能开销更小。然而,其同步能力有限,使用不当容易产生线程安全问题。
核心特性
可见性保证(Visibility)
- 当某个线程修改
volatile变量的值时,该值会立即被强制刷新到主内存 - 其他线程读取该变量时,会从主内存重新加载最新值,而非使用本地线程缓存
- 解决了多线程环境下因 CPU 缓存导致的数据不一致问题
有序性保证(Ordering)
- 禁止编译器和处理器对
volatile变量的读写操作进行指令重排序 - 确保:
volatile写操作之前的任何读写操作不会被重排序到写之后volatile读操作之后的任何读写操作不会被重排序到读之前
- 建立 happens-before 关系,确保多线程间的操作顺序可见性
不保证原子性(Non-Atomicity)
volatile无法保证复合操作的原子性(如i++)- 复合操作由多个步骤组成,中间可能被其他线程中断
内存语义
volatile 写操作的内存屏障
[普通写/读操作] → [StoreStore 屏障] → [volatile 写] → [StoreLoad 屏障]
volatile 读操作的内存屏障
[volatile 读] → [LoadLoad 屏障] → [LoadStore 屏障] → [普通写/读操作]
内存屏障的作用:
- StoreStore 屏障:确保 volatile 写之前的普通写操作已刷新到主内存
- StoreLoad 屏障:确保 volatile 写完成后,后续的读操作能看到所有之前的写入
- LoadLoad 屏障:确保 volatile 读之后的操作不会被重排序到读之前
- LoadStore 屏障:确保 volatile 读之后的写操作不会被重排序到读之前
经典应用场景
状态标志(最常用)
public class ShutdownHandler {
private ;
{
shutdownRequested = ;
}
{
(!shutdownRequested) {
}
}
}


