AtomicReference 通过CPU的CAS指令实现引用的无锁原子更新,保证“引用本身”而非对象内容的线程安全,支持compareAndSet等原子操作,并需注意ABA问题。

AtomicReference 通过底层 CPU 的 CAS(Compare-And-Swap)指令实现引用对象的无锁原子更新,不依赖 synchronized 或锁机制,而是靠硬件级原子操作保证线程安全。
CAS 是核心机制
AtomicReference 的所有原子更新方法(如 compareAndSet、getAndSet、updateAndGet)最终都基于 Unsafe 类调用 CPU 的 CAS 指令。该指令以原子方式完成“读取当前值 → 比较是否等于预期值 → 若是则写入新值”三步,整个过程不可中断。
- 如果当前值与预期值相等,更新成功,返回 true;否则失败,返回 false
- CAS 失败时不会阻塞线程,通常配合循环重试(如自旋)实现“乐观锁”语义
- Java 9+ 中部分方法(如
weakCompareAndSet)还提供弱版本 CAS,允许偶然失败,适用于某些高性能场景
引用地址而非内容的原子性
AtomicReference 保证的是“对象引用本身”的原子更新,不是对象内部状态的线程安全。它存储的是对象在堆中的内存地址,CAS 操作比对和替换的都是这个地址值。
- 即使你用
new Person("Alice")创建对象并存入 AtomicReference,后续修改该 Person 实例的 name 字段,AtomicReference 并不感知——它只管“指向谁”是否变了 - 若需保证对象内容也原子,需让对象本身不可变(如 final 字段 + 无 setter),或结合其他同步手段
典型用法:自旋更新与链表操作
无锁编程中常见模式是用循环 + compareAndSet 实现状态变更,比如实现一个无锁栈或计数器。
立即学习“Java免费学习笔记(深入)”;
- 例如原子更新一个 Integer 计数器:
while (!counter.compareAndSet(expected, expected + 1)) { expected = counter.get(); } - 又如构建无锁单链表节点:
Node newNode = new Node(value); newNode.next = head.get(); while (!head.compareAndSet(newNode.next, newNode)) { /* 重试 */ } - 注意 ABA 问题:某个引用被改回原值(A→B→A),CAS 会误判成功。必要时可用
AtomicStampedReference加版本戳规避
与 volatile 的区别
AtomicReference 内部字段用 volatile 修饰,保证可见性和禁止重排序,但 volatile 仅提供读写原子性;而 AtomicReference 提供的是“读-改-写”复合操作的原子性。
-
volatile Person p:每次读写都可见,但p = new Person()是原子的,p.name = "x"不是 -
AtomicReference<person> ref</person>:支持ref.compareAndSet(old, new)这种带条件的原子赋值 - 简单赋值(
ref.set(x))等价于 volatile 写;ref.get()等价于 volatile 读


















