volatile仅保证可见性和有序性,不保证原子性;适用于状态标志等单次写、多线程读的场景,如启停控制;不可用于count++等复合操作,需用atomicinteger或synchronized。

volatile 不能实现“同步”,它只保证可见性和禁止指令重排序,不提供原子性。用它做线程间状态通知(比如开关、标志位)是合适的,但别指望靠它完成 count++ 这类复合操作。
适合 volatile 的典型场景:状态标志
当一个线程负责设置某个布尔状态(如 running = false),其他线程轮询该状态决定是否继续执行时,volatile 就够用了。
- 写线程修改变量后,读线程能立即看到最新值(可见性)
- JVM 不会对 volatile 读写与前后普通读写做重排序(有序性)
- 不需要加锁,开销极小,适合高频读、低频写的控制信号
不能用 volatile 的情况:非原子操作
下面这段代码是错的:
private volatile int counter = 0;
// 多个线程同时调用
public void increment() {
counter++; // 读-改-写,三步,volatile 不保证这三步原子
结果可能丢失更新。必须用 AtomicInteger 或 synchronized。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
正确用法示例:安全的启停控制
启动一个后台任务,主线程通过 volatile 变量控制其退出:
public class TaskRunner {
private volatile boolean running = true;
public void start() {
new Thread(() -> {
while (running) {
doWork();
Thread.sleep(100);
}
System.out.println("Stopped.");
}).start();
}
public void stop() {
running = false; // 立即对工作线程可见
}
}
注意:running 是单次写入(stop 调用一次),多线程只读,无竞态,符合 volatile 使用前提。
配合 happens-before 理解更稳
volatile 写操作 happens-before 后续任意线程对该变量的读操作。这意味着:
- 写之前的所有内存操作,对后续读到该 volatile 变量的线程也可见(不只是变量本身)
- 可用来发布对象引用(如初始化完的对象赋给 volatile 字段),避免读到半初始化状态
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










