AtomicInteger 通过 Unsafe.compareAndSwapInt 实现 CAS 原子操作,无需锁即可保证线程安全;提供 incrementAndGet、decrementAndGet、addAndGet、compareAndSet 等原子方法,适用于高并发计数场景。

用 AtomicInteger 实现高并发计数,核心是避开锁、依赖 CPU 的 CAS(Compare-And-Swap)指令完成原子更新,既高效又线程安全。
为什么 AtomicInteger 能保证线程安全
AtomicInteger 底层调用的是 Unsafe.compareAndSwapInt,这是一个由 JVM 映射到硬件的原子操作:先比较当前值是否等于预期值,相等才更新为新值,整个过程不可中断。多个线程同时执行 incrementAndGet() 时,只有一个能成功,失败者自动重试(底层循环实现),无需 synchronized 或 Lock。
常用计数操作及写法
以下方法全部是原子的,可直接用于高并发场景:
-
自增计数:
counter.incrementAndGet()—— 返回加 1 后的值 -
自减计数:
counter.decrementAndGet()—— 返回减 1 后的值 -
加指定数值:
counter.addAndGet(5)—— 原子加 5 并返回结果 -
条件更新(带判断):
counter.compareAndSet(expected, updated)—— 仅当当前值等于 expected 时设为 updated,返回是否成功
典型使用示例(Web 请求计数器)
比如统计某接口每秒调用量:
private static final AtomicInteger requestCounter = new AtomicInteger(0);
public void handleRequest() {
// 每次请求原子递增
int currentCount = requestCounter.incrementAndGet();
// 可选:达到阈值触发告警(注意此处非原子,如需严格一致建议用 compareAndSet 配合循环)
if (currentCount > 1000) {
alert("QPS 超限!");
requestCounter.set(0); // 重置(也是原子操作)
}
}
注意:set(0) 和 get() 本身也是原子的,但 if + set 组合不是原子的;若需“检查并重置”原子语义,应改用 getAndSet(0) 或配合 CAS 循环实现。
注意事项与常见误区
- 不能替代复杂业务逻辑:它只保障单个变量的读-改-写原子性,不适用于涉及多个变量或数据库操作的复合场景
-
无内存屏障副作用需留意:虽然 volatile 语义已内置,但在某些极端重排序场景下,若需更强可见性控制,可搭配
Thread.onSpinWait()或显式ForkJoinPool等机制 -
过度争用会降低性能:当线程极多、更新极频繁(如每纳秒都调用),CAS 失败重试开销会上升,此时可考虑
LongAdder(JDK8+),它通过分段累加减少冲突

















