CAS 原理
CAS(Compare-And-Swap)是一种乐观锁机制:CAS 伪代码
CAS 的优缺点
| 优点 | 缺点 |
|---|---|
| 无锁,性能高 | ABA 问题 |
| 避免死锁 | 自旋开销 |
| 适合低竞争场景 | 只能保证单个变量的原子性 |
基本原子类
AtomicInteger
常用方法
AtomicLong
用法与 AtomicInteger 相同,用于 long 类型。AtomicBoolean
引用原子类
AtomicReference
用于对象引用的原子操作。AtomicStampedReference - 解决 ABA 问题
ABA 问题:值从 A 变为 B 再变回 A,CAS 无法检测到这种变化。AtomicMarkableReference
使用布尔标记代替版本号。数组原子类
AtomicIntegerArray
AtomicLongArray
AtomicReferenceArray
字段原子更新器
用于原子更新对象的某个字段,无需将整个对象变为原子类。AtomicIntegerFieldUpdater
使用限制
累加器(JDK 8+)
针对高并发累加场景优化,性能优于 AtomicLong。LongAdder
LongAdder vs AtomicLong
| 特性 | AtomicLong | LongAdder |
|---|---|---|
| 实现 | 单个变量 CAS | 分散热点,多个 Cell |
| 低竞争性能 | 好 | 稍差(Cell 管理开销) |
| 高竞争性能 | 差(CAS 频繁失败) | 好 |
| 获取精确值 | 简单 | 需要汇总所有 Cell |
LongAccumulator
更通用的累加器,支持自定义累加函数。DoubleAdder / DoubleAccumulator
用于浮点数的累加。原子类选择指南
| 场景 | 推荐类 |
|---|---|
| 计数器(低并发) | AtomicInteger / AtomicLong |
| 计数器(高并发) | LongAdder |
| 对象引用 | AtomicReference |
| 解决 ABA 问题 | AtomicStampedReference |
| 数组元素 | AtomicIntegerArray / AtomicLongArray |
| 对象字段 | AtomicIntegerFieldUpdater |
| 自定义累加 | LongAccumulator |
小结
- 原子类基于 CAS 实现,无锁、高性能
- 基本原子类:AtomicInteger、AtomicLong、AtomicBoolean
- 引用原子类:AtomicReference、AtomicStampedReference(解决 ABA)
- 数组原子类:AtomicIntegerArray、AtomicLongArray
- 字段更新器:AtomicIntegerFieldUpdater 等
- 累加器:LongAdder(高并发累加首选)、LongAccumulator
- 根据并发程度和使用场景选择合适的原子类