cas是compare-and-swap(比较并交换)的缩写,是一种cpu硬件支持的原子指令,通过比较内存值v与预期值a是否相等来决定是否将v更新为新值b;它采用乐观锁策略,失败时自旋重试,避免线程阻塞和上下文切换,在低竞争场景下性能优于synchronized。

AtomicInteger 通过底层的 CAS(Compare-And-Swap)指令实现线程安全的无锁更新,不依赖 synchronized 或 lock,而是靠 CPU 硬件指令保证原子性。
CAS 是什么?为什么能替代锁?
CAS 是一种乐观并发策略:执行时先检查变量当前值是否等于预期值,如果是,才把新值写入;否则失败重试。它不阻塞线程,没有上下文切换开销,适合高并发、低竞争场景。
Java 中,Unsafe.compareAndSwapInt 是 CAS 的核心方法,由 JVM 调用本地代码,最终映射为 CPU 的 cmpxchg 指令(x86 平台)。这个指令本身是原子的,由硬件保障。
AtomicInteger 的 incrementAndGet 是怎么工作的?
调用 incrementAndGet() 时,内部循环执行 CAS:
- 读取当前值
current - 计算期望新值
next = current + 1 - 用
unsafe.compareAndSwapInt(this, valueOffset, current, next)尝试更新 - 如果返回
true,说明更新成功,直接返回next;否则说明期间被其他线程改过,重新读取再试
整个过程没有锁,但可能因竞争而自旋重试——这就是“无锁”不是“零开销”,而是“避免阻塞和锁管理成本”。
ABA 问题及其在 AtomicInteger 中的影响
ABA 问题:变量从 A → B → A,CAS 会误判为“没变过”,从而错误更新。这在引用类型中可能导致逻辑错误(如栈操作),但在 AtomicInteger 这类纯数值计数场景中,ABA 通常无害。
原因:对计数器而言,“值又变回 A” 和 “根本没变” 对业务语义等价(比如总请求数从 100→101→100,只说明中间有增有减,不影响最终统计逻辑)。所以 AtomicInteger 不处理 ABA,也无需引入 AtomicStampedReference。
使用注意点
- 单个操作(如
getAndIncrement)是原子的,但组合操作(如“先 get 再 set”)仍需额外同步 - 高竞争下自旋耗 CPU,极端情况性能可能不如锁(不过多数业务场景不明显)
- 所有原子类都基于 Unsafe,不能随意反射修改其内部 value 字段,会破坏原子性保证
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











