AtomicReference通过CPU的CAS指令实现引用的无锁原子更新,保证“读-比-写”三步不可中断;其compareAndSet等方法封装CAS,支持乐观更新、自旋重试及函数式更新,但仅保障引用本身原子性,不保护对象内部状态。

AtomicReference 通过底层 CPU 的 CAS(Compare-And-Swap)指令实现引用对象的无锁更新,不依赖 synchronized 或锁机制,而是靠硬件保证原子性。
核心原理:CAS 指令保障原子性
CAS 是一种 CPU 原子指令,它会同时完成“读取当前值 → 比较是否等于预期值 → 如果相等则更新为新值”三个步骤,整个过程不可中断。AtomicReference 的 compareAndSet(expected, updated) 方法正是封装了这一操作:
- 如果当前引用值 == expected,就将引用设为 updated,并返回 true;
- 否则不做修改,返回 false,调用方可重试(如配合循环);
- JVM 将其编译为对应平台的 CAS 汇编指令(如 x86 上是
cmpxchg),由硬件直接支持。
如何安全更新引用对象(典型用法)
直接替换引用本身是线程安全的(引用赋值在 Java 中是原子操作),但 AtomicReference 的价值在于「条件更新」——即只在满足某种状态时才更新。常见模式如下:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 使用
compareAndSet(oldRef, newRef)实现乐观更新; - 配合循环(自旋)处理 CAS 失败,例如实现无锁栈或计数器;
- 用
updateAndGet(operand)或getAndUpdate(operand)执行函数式更新(JDK 8+); - 避免对引用指向的对象内容做非原子修改——AtomicReference 只管引用本身,不管对象内部字段是否线程安全。
注意:引用不变 ≠ 对象不可变
AtomicReference 保证的是“引用地址的更新”是原子的,不是“对象状态”的线程安全:
立即学习“Java免费学习笔记(深入)”;
- 如果你用
new AtomicReference<StringBuilder>(),多个线程仍可能并发修改同一个 StringBuilder 的内容,引发数据错乱; - 若需对象状态也安全,应选用不可变对象(如 String、LocalDateTime),或对象自身具备同步机制(如 StringBuffer);
- 也可结合 volatile 字段 + 手动加锁,但那就脱离了“无锁”初衷。
扩展:AtomicReference 的进阶能力
除了基本 CAS,它还支持更实用的原子操作:
-
weakCompareAndSet():语义更弱(不保证 happens-before),适合高性能场景(如伪随机数生成器); -
getAndSet(newRef):先取旧值再设新值,原子完成; -
accumulateAndGet(x, accumulatorFunction):传入二元函数做原子累积(如加法、合并); - 与
VarHandle(JDK 9+)配合,可获得更底层、更灵活的原子访问能力。

















