一、CAS 核心原理
1. 定义与核心概念
- CAS(Compare And Swap):比较与交换,是 CPU 硬件层面的原子指令,用于实现无锁同步。
- 核心参数:内存值 V、预期值 E、新值 N。
- 执行逻辑:当且仅当内存值 V == 预期值 E 时,将内存值更新为 N;无论是否更新,均返回原始内存值 V,整个过程原子性由硬件保障。
- 本质:无锁算法(非阻塞同步)、乐观锁的实现方式。
2. Java 中的 CAS 实现
- 底层依赖
sun.misc.Unsafe类的 native 方法,提供三种类型的 CAS 操作:compareAndSwapObject:对象类型compareAndSwapInt:int 类型compareAndSwapLong:long 类型
Unsafe类风险:直接操作内存,类似 C 语言指针,使用不当会破坏 Java 安全性,需谨慎使用。
3. 底层源码分析(Hotspot 虚拟机)
// unsafe.cpp核心逻辑
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) {
UnsafeWrapper("Unsafe_CompareAndSwapInt");
oop p = JNIHandles::resolve(obj);
jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);
// 核心CAS指令调用
return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
}
UNSAFE_END
- x86 架构实现 :通过
cmpxchgl指令完成,多处理器环境下添加lock前缀保证内存屏障。 - 执行流程 :
- 将预期值 E 存入 eax 寄存器
- 比较 eax 与目标内存地址的值
- 相等则替换为新值 N,否则将内存值存入 eax
- 返回 eax 的值,判断 CAS 是否成功
4. CAS 的三大缺陷
| 缺陷 | 描述 |
|---|---|
| 自旋开销 | 高并发下 CAS 长时间失败,线程自旋会占用大量 CPU 资源 |
| 只能原子操作单个变量 | 无法直接实现多个共享变量的原子操作(需组合成对象间接实现) |
| ABA 问题 | 数据被修改为 B 后又恢复为 A,其他线程无法感知变化 |
5. ABA 问题解决方案
- 问题演示:

- 解决方案 :
- AtomicStampedReference :带版本号的原子引用,通过版本号递增保证唯一性
- 构造参数:
AtomicStampedReference(V initialRef, int initialStamp) - CAS 方法:
compareAndSet(V expectedRef, V newRef, int expectedStamp, int newStamp)
- 构造参数:
- AtomicMarkableReference:简化版,仅通过 boolean 标记是否被修改(不关心修改次数)
- AtomicStampedReference :带版本号的原子引用,通过版本号递增保证唯一性
二、Atomic 原子操作类体系
1. 核心分类与作用
| 类别 | 代表类 | 作用 |
|---|---|---|
| 基本类型原子类 | AtomicInteger、AtomicLong、AtomicBoolean | 原子更新基本数据类型 |
| 引用类型原子类 | AtomicReference、AtomicStampedReference、AtomicMarkableReference | 原子更新对象引用 |
| 数组类型原子类 | AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray | 原子更新数组元素 |
| 对象属性原子修改器 | AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicReferenceFieldUpdater | 原子更新对象的字段(无需修改原类) |
| 原子累加器(JDK1.8+) | LongAdder、DoubleAdder、LongAccumulator、DoubleAccumulator | 高并发场景下高效累加,解决 AtomicLong 自旋瓶颈 |
2. 常用类详解
(1)基本类型原子类(以 AtomicInteger 为例)
- 核心方法:
getAndIncrement():原子自增,返回旧值incrementAndGet():原子自增,返回新值addAndGet(int delta):原子累加 delta,返回新值compareAndSet(int expect, int update):CAS 更新
- 实现原理:基于 Unsafe 的 CAS 操作 + 自旋重试
(2)对象属性原子修改器(AtomicIntegerFieldUpdater)
- 核心约束:
- 目标字段必须是
volatile类型(保证可见性) - 只能是实例变量(不能是 static)
- 不能是 final 变量(与修改语义冲突)
- 字段类型必须与修改器匹配(int 对应 AtomicIntegerFieldUpdater)
- 访问权限需一致(调用者能通过反射访问该字段)
- 目标字段必须是
(3)原子累加器(LongAdder)
-
设计初衷:解决高并发下 AtomicLong 的自旋冲突问题
-
核心原理 :分散热点,将累加值分散到
Cell[]数组中

-
核心结构:
base:无竞争时的累加基数Cell[]:竞争时的分散存储数组(大小为 2 的幂,与 CPU 核数相关)cellsBusy:自旋锁,用于 Cell 数组的初始化和扩容
-
与 AtomicLong 对比:| 特性 | AtomicLong | LongAdder ||------|------------|-----------|| 并发性能 | 低并发优秀,高并发自旋冲突严重 | 高并发下性能更优(分散热点) || 准确性 | 完全准确(每次操作原子性) | sum () 返回近似值(无锁累加) || 适用场景 | 低并发、需要精确计数 | 高并发、写多读少、允许近似计数 |
3. 典型应用场景
- 并发计数器(如接口访问量统计)
- 无锁数据结构(如 ConcurrentLinkedQueue)
- 线程安全的状态管理(如状态标志位)
- AQS 框架底层实现(ReentrantLock、CountDownLatch 等)