volatile关键字用于保证多线程环境下共享变量的可见性和禁止指令重排序,通过内存屏障确保写操作立即刷新到主内存、读操作强制从主内存获取最新值,并建立happens-before关系以保障操作顺序与可见性;它适用于状态标志位、DCL单例模式等场景,但不保证原子性,复合操作需依赖synchronized或Atomic类。

在Java中,
volatile
volatile
要使用
volatile
volatile
当一个线程写入一个
volatile
volatile
volatile
我们来看一个简单的例子。假设我们有一个标志位,用来通知另一个线程停止工作:
public class Worker {
// 没有volatile,stopRequested可能被线程缓存,导致线程无法及时停止
// private boolean stopRequested;
// 加上volatile,确保stopRequested的修改对所有线程立即可见
private volatile boolean stopRequested;
public void requestStop() {
stopRequested = true;
}
public boolean isStopRequested() {
return stopRequested;
}
public void run() {
while (!stopRequested) {
// 模拟工作
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("Worker is running...");
}
System.out.println("Worker stopped.");
}
public static void main(String[] args) throws InterruptedException {
Worker worker = new Worker();
Thread workerThread = new Thread(worker::run);
workerThread.start();
Thread.sleep(1000); // 让worker跑一会儿
System.out.println("Main thread requesting stop...");
worker.requestStop(); // 主线程修改stopRequested
workerThread.join(); // 等待worker线程结束
System.out.println("Main thread finished.");
}
}在这个
Worker
stopRequested
volatile
run
while (!stopRequested)
stopRequested
main
Worker
volatile
main
stopRequested
Worker
stopRequested
立即学习“Java免费学习笔记(深入)”;
volatile
这是一个非常常见的误解。
volatile
考虑一个简单的自增操作:
count++
count
count
count
如果
count
volatile
count
count
count
count
count
count
count
count
count
最终结果是 1,而不是我们期望的 2。尽管
volatile
如果你需要保证原子性,你需要使用
java.util.concurrent.atomic
AtomicInteger
AtomicLong
synchronized
Lock
volatile
要理解
volatile
volatile
volatile
volatile
volatile
volatile
volatile
volatile
volatile
volatile
volatile
volatile
这些语义是通过内存屏障(Memory Barrier)来实现的。在 HotSpot JVM 中,
volatile
volatile
StoreStore
volatile
volatile
StoreLoad
volatile
volatile
LoadLoad
volatile
volatile
LoadStore
volatile
volatile
这些屏障阻止了编译器和处理器对指令进行重排序,从而维护了
volatile
volatile
尽管
volatile
常见误区:
volatile
synchronized
volatile
i++
volatile
synchronized
Lock
volatile
volatile
volatile
volatile
volatile
volatile
Atomic
synchronized
最佳实践:
作为状态标志位:
volatile
stopRequested
作为单例模式中的 DCL(Double-Checked Locking)屏障: 在实现线程安全的单例模式时,如果使用 DCL,必须将单例对象声明为
volatile
instance
null
public class Singleton {
private volatile static Singleton instance; // 必须是volatile
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) { // 第一次检查
synchronized (Singleton.class) {
if (instance == null) { // 第二次检查
instance = new Singleton(); // 这步操作可能被重排序
}
}
}
return instance;
}
}instance = new Singleton()
instance
instance
volatile
instance
null
instance
null
volatile
有限状态机: 当一个变量在多个线程之间传递,并且它的值代表了某个有限状态机中的状态时,
volatile
总的来说,
volatile
synchronized
Atomic
以上就是如何在Java中使用volatile关键字保证可见性的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号