volatile 关键字的使用
|
💖The Begin💖点点关注,收藏不迷路💖
|
volatile 关键字用于确保变量在多线程环境中的可见性和禁止指令重排序,但它不能保证操作的原子性。以下是volatile的几个使用场景:
1、标志位
当线程需要等待某个条件成立才能继续执行时,可以使用volatile修饰的布尔变量作为标志位。
volatile boolean initialized = false;
// 初始化线程
Thread initializer = new Thread(() -> {
// 初始化资源
initialized = true;
});
// 等待线程
Thread waiter = new Thread(() -> {
while (!initialized) {
// 等待初始化完成
}
// 执行后续操作
});
initializer.start();
waiter.start();
2、传递不依赖当前值的变量
当变量的值被更新,且更新操作不依赖于其当前值时,volatile可确保更新立即对其他线程可见。例如,一个简单的计数器,每个线程只是简单地增加计数器的值,而不需要读取当前计数器的值作为计算的一部分。
3、双重检查锁定(简化)
在单例模式的双重检查锁定实现中,volatile确保单例对象在所有线程中的可见性。
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
4、注意事项
1、不能保证原子性:如果操作包含多个步骤,如 i++,那么 volatile 关键字无法确保这些步骤的原子性。在这种情况下,应该使用 synchronized 或其他并发工具(如 AtomicInteger)。
2、内存屏障:volatile 的使用可能会引入内存屏障,这会增加一些性能开销,但通常这种开销远低于 synchronized。

|
💖The End💖点点关注,收藏不迷路💖
|

1097

被折叠的 条评论
为什么被折叠?



