在 Java 多线程中,volatile 是一个轻量级的同步机制,主要用来保证可见性和禁止指令重排序,但不保证原子性。
下面从 是什么、怎么用、适用场景、注意事项 四个方面说明。
volatile 修饰的变量:
volatile 变量,其他线程能立即看到最新值i++ 这种操作不是线程安全的public class VolatileDemo {
// 使用 volatile 修饰共享变量
private static volatile boolean flag = false;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
while (!flag) {
// 等待 flag 变为 true
}
System.out.println("线程结束");
});
t1.start();
Thread.sleep(1000);
flag = true; // 主线程修改,t1 立即可见
}
}
✅ 如果不加 volatile,t1 可能一直看不到 flag 的变化,导致死循环。
volatile int value = 0;
线程 A 修改 value,线程 B 能立刻读到新值。
public class Singleton {
private static volatile Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
不加 volatile 可能导致:
private static volatile int count = 0;
// 多线程执行
count++; // 非线程安全
原因:count++ 是 读-改-写 三步操作
✅ 正确方式:
AtomicInteger count = new AtomicInteger(0);
count.incrementAndGet();
或使用 synchronized / Lock
✅ 适合:
running = false)❌ 不适合:
| 特性 | volatile | synchronized |
|---|---|---|
| 可见性 | ✅ | ✅ |
| 原子性 | ❌ | ✅ |
| 阻塞 | 否 | 是 |
| 性能 | 高 | 较低 |
volatile 解决“看得见”,不解决“算得对”。
如果你愿意,我可以给你:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。