前言

最近看volatileAtomicBoolean,有时候搞不懂到时啥时候使用,因此问了AI,做一下记录,方便自己查阅。

正文

什么是volatile?

volatile 是一个关键字,修饰变量,干两件事:

  1. 可见性:一个线程改了值,另一个线程立刻能看到,不会被 CPU 缓存糊弄

  2. 禁止指令重排:写操作前的代码不会被重排到写操作后(配合 happens-before 规则)

但它不保证原子性!

volatile boolean flag = false;
// 线程 A
flag = true;  // 单步写操作,没问题
// 线程 B
if (flag) {   // 能看到最新值
    ...
}

这个场景完全够用。但下面这种就不行了:

volatile int count = 0;
// 多线程同时执行
count++;  // 读-改-写三步操作,volatile 保护不了

什么是AtomicBoolean?

AtomicBoolean 是一个,内部用 volatile boolean + CAS(Compare And Swap) 指令实现的。

private volatile int value;  // 内部实现,用 int 存 0/1

它提供的不是"可见性"这么简单,而是整个操作一步到位

AtomicBoolean started = new AtomicBoolean(false);

// 只有第一个线程能成功,其他线程直接返回 false
if (started.compareAndSet(false, true)) {
    // 初始化逻辑,只会执行一次
}

compareAndSet原子的——读、比较、写三步在 CPU 层面是一条指令,中间不会被打断。

用volatile的情况

纯状态标记,且只有一个线程写,多个线程读:

volatile boolean isShuttingDown = false;

// 多个工作线程
while (!isShuttingDown) {
    doWork();
}

// 管理线程
isShuttingDown = true;

或者你只做单次赋值

volatile BluetoothDevice bondedDevice;
bondedDevice = device;  // 直接写,不需要原子性

用 AtomicBoolean的情况

需要"检查再修改",而且可能有多个线程同时竞争:

// 只初始化一次的 RFCOMM 服务
AtomicBoolean rfcommInitialized = new AtomicBoolean(false);

void initRfcomm() {
    if (rfcommInitialized.compareAndSet(false, true)) {
        // 这里只会有一个线程进来
        setupRfcommSocket();
    }
}

再比如你之前那个 AA 连接流程里的状态机:

enum ConnectionState { IDLE, PAIRING, CONNECTING, CONNECTED }
AtomicReference<ConnectionState> state = 
    new AtomicReference<>(ConnectionState.IDLE);
// 只有当前是 IDLE 才能切到 PAIRING
if (state.compareAndSet(IDLE, PAIRING)) {
    startPairing();
}

对比

特性volatileAtomicBoolean
可见性保证保证
有序性禁止指令重排禁止指令重排
原子性不保证保证 (CAS 机制)
底层实现CPU 内存屏障CAS (Compare-And-Swap)
性能开销极低较低 (无锁,但有 CAS 开销)
适用场景状态标志位、DCL 单例并发计数器、开关控制、状态机

性能上:

  • volatile 几乎没有额外开销,就是内存屏障

  • AtomicBoolean 在高并发下 CAS 失败会自旋重试,竞争激烈时可能浪费 CPU

但在 Android 车载这种并发量不高、但正确性要求高的场景,AtomicBoolean 用起来比你自己加 synchronized 轻量多了。

小结

volatile 保证可见性和有序性,但不保证原子性;AtomicBoolean 在 volatile 的基础上额外保证了操作的原子性。

参考文章

  1. AI

相关文章

笔友城堡 - 可定义的个人主页

暂无评论

评论审核已启用。您的评论可能需要一段时间后才能被显示。

none
暂无评论...