AtomicInteger 能做到无锁原子性,因其封装 volatile int 并通过 Unsafe 调用 CPU 的 CAS 指令:先读取当前值,仅当内存值与预期一致时才更新,否则自旋重试,整个过程由硬件保证原子性且不阻塞线程。

Java 中用 AtomicInteger 实现无锁原子自增,核心是调用其 incrementAndGet() 或 getAndIncrement() 方法,底层依赖 CPU 的 CAS(Compare-And-Swap)指令,无需 synchronized 或锁机制。
为什么 AtomicInteger 能做到无锁原子性
AtomicInteger 封装了一个 volatile int,保证可见性;所有修改操作(如自增)都通过 Unsafe 类调用本地 CAS 指令完成。CAS 会先读取当前值,再尝试更新:只有当内存中的值与预期一致时才成功替换,否则重试——整个过程由硬件保证原子性,不阻塞线程。
常用自增方法及区别
两个最常用的自增方法语义不同,选错会影响逻辑:
-
incrementAndGet():先自增,再返回新值(类似++i) -
getAndIncrement():先返回当前值,再自增(类似i++)
例如:AtomicInteger counter = new AtomicInteger(0);int a = counter.incrementAndGet(); // a=1,counter=1int b = counter.getAndIncrement(); // b=1,counter=2
在多线程中安全使用示例
直接在共享变量上操作即可,不需要额外同步:
立即学习“Java免费学习笔记(深入)”;
AtomicInteger count = new AtomicInteger(0);
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
count.incrementAndGet(); // 线程安全的自增
}
};
Thread t1 = new Thread(task);
Thread t2 = new Thread(task);
t1.start(); t2.start();
t1.join(); t2.join();
System.out.println(count.get()); // 总是输出 2000
注意避免常见误区
虽然自增是原子的,但复合操作仍需小心:
- ❌
if (counter.get() —— “读-判-改”不是原子的,可能引发竞态 - ✅ 改用
updateAndGet或循环 CAS:counter.updateAndGet(v -> v - ⚠️ 不要把它当普通 int 用:不能直接赋值
counter = new AtomicInteger(5)(应调用set(5))


















