在 Java 中,volatile 关键字主要用于保证多线程环境下的可见性和有序性,但它不保证原子性。下面从“为什么需要它”的角度来说。
在多线程中,每个线程可能把变量从主内存拷贝到自己的**工作内存(CPU 缓存)**中:
// 线程 A
flag = true;
// 线程 B
while (!flag) {
// 可能永远看不到 flag 变成 true
}
如果没有 volatile:
flag✅ volatile 的作用之一:
一个线程修改 volatile 变量,其他线程立刻可见
JVM 和 CPU 为了性能,会对指令重排序。
例子(双重检查锁单例):
instance = new Singleton();
实际可能被拆成:
如果重排序成 1 → 3 → 2,其他线程可能拿到未初始化完成的对象
✅ volatile 的作用之二:
禁止指令重排序(建立内存屏障)
volatile int count = 0;
count++; // 不是原子操作
count++ 包含:
多线程下仍可能出错。
volatile boolean running = true;
// 线程1
running = false;
// 线程2
while (running) {
// 工作
}
private static volatile Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
volatile Object config;
| 特性 | volatile | synchronized |
|---|---|---|
| 可见性 | ✅ | ✅ |
| 原子性 | ❌ | ✅ |
| 阻塞 | ❌ | ✅ |
| 性能 | 高 | 低 |
Java 需要 volatile,是因为在多线程环境下,普通变量可能因为缓存和指令重排序,导致线程看到错误的数据或执行顺序。
如果你愿意,我也可以用图示 / 字节码 / 面试角度再讲一遍。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。