AtomicInteger 通过 CAS 实现无锁线程安全:读 volatile 值、计算新值、用 Unsafe 调用 CPU 原子指令 cmpxchg 尝试更新,失败则自旋重试;incrementAndGet 等方法均基于此循环机制,低竞争时高性能,高竞争时可能 CPU 升高。

AtomicInteger 通过底层的 CAS(Compare-And-Swap)指令实现线程安全的无锁计数,不需要 synchronized 或 Lock,性能更高、竞争较小时延迟更低。
CAS 是怎么在 AtomicInteger 中起作用的
Java 的 AtomicInteger 封装了一个 volatile int value,并通过 Unsafe 类调用 CPU 级的原子指令(如 x86 的 cmpxchg)。每次更新(如 incrementAndGet)都会:
- 读取当前值(volatile 保证可见性)
- 基于当前值计算新值(比如 +1)
- 用 CAS 指令尝试将内存中的值从“旧值”更新为“新值”
- 如果期间有其他线程修改了该值(即旧值已不匹配),CAS 失败,就重试(自旋)直到成功
常用方法背后的 CAS 行为
这些方法都基于 CAS 循环,不是简单的一条指令:
- incrementAndGet():循环执行 compareAndSet(old, old+1),返回新值
- getAndIncrement():先读当前值 v,再 try compareAndSet(v, v+1),成功则返回 v(旧值)
- compareAndSet(expected, newValue):直接暴露 CAS 原语,返回 boolean 表示是否成功
- addAndGet(delta):类似 incrementAndGet,但加的是任意 delta
注意:所有写操作都对 volatile value 生效,因此对其他线程立即可见;所有读操作也走 volatile 读,保证获取最新值。
为什么叫“无锁”但可能自旋?
它不使用操作系统互斥锁(如 Monitor),所以没有线程挂起/唤醒开销,属于乐观并发策略。但高竞争下会频繁 CAS 失败并重试(自旋),导致 CPU 占用升高。这不是 bug,而是设计取舍——低竞争时极快,高竞争时需结合其他手段(如 LongAdder)。
一个典型使用场景示例
统计网页访问量,多个线程并发调用:
private static final AtomicInteger visitCount = new AtomicInteger(0);public static void recordVisit() { visitCount.incrementAndGet(); }
这段代码天然线程安全,无需额外同步。即使上千请求并发执行 recordVisit,visitCount 的最终值也一定准确。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











