在 Java 中,volatile 关键字主要用于保证变量的可见性和禁止指令重排序,但不保证原子性。下面是它的典型适用场景和注意事项。
当一个变量被 volatile 修饰后:
✅ 适用场景:一个线程写,多个线程读
volatile boolean running = true;
// 线程1
while (running) {
// do something
}
// 线程2
running = false; // 其他线程立刻可见
常用于控制线程启停、任务开关等。
volatile boolean isShutdown = false;
在单例模式中,volatile 防止对象未初始化完成就被使用。
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;
}
}
原因:
new Singleton() 不是原子操作volatile 保证初始化完成前不会对外暴露引用用于发布“只读或初始化后不变”的对象。
volatile Config config;
// 初始化线程
config = loadConfig();
// 使用线程
if (config != null) {
config.getA();
}
volatile 不能保证 i++ 的线程安全
volatile int count = 0;
count++; // 非原子操作,线程不安全
应使用:
AtomicIntegersynchronizedLockvolatile int a;
volatile int b;
// 线程1
a = 1;
b = 2;
// 线程2
if (b == 2) {
System.out.println(a); // 可能读到 0
}
volatile 不能替代锁。
| 特性 | volatile | synchronized |
|---|---|---|
| 可见性 | ✅ | ✅ |
| 原子性 | ❌ | ✅ |
| 互斥 | ❌ | ✅ |
| 性能 | 高 | 较低 |
volatile 适合:一个线程写、多个线程读,且操作是原子的场景。
如果你有具体代码场景,我可以帮你判断该不该用 volatile。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。