题目
请解释 volatile 关键字在 Java 中的作用
信息
- 类型:问答
- 难度:⭐
考点
volatile关键字,内存可见性,指令重排序
快速回答
volatile 关键字主要有两个核心作用:
- 保证变量的内存可见性:所有线程都能立即看到该变量的最新值
- 禁止指令重排序优化:确保代码执行顺序与程序顺序一致
典型应用场景:状态标志位、双重检查锁定等
解析
1. 原理说明
Java 内存模型(JMM)规定:
- 可见性问题:普通变量修改后可能暂存在工作内存,其他线程无法立即感知
- 重排序问题:编译器和处理器可能优化指令执行顺序
volatile 通过以下机制解决:
- 写操作时强制刷新主内存,并使其他线程缓存失效
- 通过内存屏障禁止指令重排序(LoadStore/LoadLoad/StoreStore/StoreLoad)
2. 代码示例
// 状态标志位示例
public class TaskRunner {
private volatile boolean running = true;
public void stop() { running = false; }
public void run() {
while (running) {
// 执行任务
}
}
}
// 双重检查锁定示例(单例模式)
class Singleton {
private static volatile Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton(); // volatile 防止重排序
}
}
}
return instance;
}
}3. 最佳实践
- 仅用于修饰独立变量(如状态标志)
- 结合 synchronized 实现更复杂的原子操作
- 在单例模式的双重检查锁定中必须使用
4. 常见错误
- 误认为 volatile 能保证原子性(如 i++ 操作)
- 过度使用导致性能下降(频繁刷新内存)
- 依赖 volatile 实现复杂同步逻辑(应使用锁机制)
5. 扩展知识
- Happens-Before 原则:volatile 写操作先于后续读操作
- 与 synchronized 对比:synchronized 保证原子性+可见性,volatile 仅保证可见性和有序性
- 适用场景:多线程共享状态标志、一次性安全发布对象