atomicinteger 通过 volatile 变量 + cas 循环实现无锁原子自增,incrementandget() 先增后返,getandincrement() 先返后增,addandget() 支持任意增量,compareandset() 提供条件更新;单个方法原子,复合操作仍需同步。

Java 中用 AtomicInteger 实现无锁原子自增,核心是调用其 incrementAndGet() 或 getAndIncrement() 方法——它们底层基于 CPU 的 CAS(Compare-And-Swap)指令,不依赖 synchronized 或 lock,天然线程安全。
为什么不用 synchronized 也能保证原子性?
AtomicInteger 内部持有一个 volatile int value,所有读写都遵循 volatile 语义;关键的自增操作(如 incrementAndGet)通过 Unsafe.compareAndSet 循环尝试:先读当前值,计算新值,再用 CAS 原子地判断“当前值是否仍等于刚读到的值”,是则更新并退出,否则重试。整个过程无显式锁,也无阻塞。
常用自增方法及区别
-
incrementAndGet():先自增,再返回新值(类似++i) -
getAndIncrement():先返回当前值,再自增(类似i++) -
addAndGet(int delta):加指定增量后返回新值,支持任意步长 -
compareAndSet(expected, updated):手动控制条件更新,适合更复杂的原子逻辑
一个典型使用示例
比如统计接口调用次数:
private static final AtomicInteger requestCount = new AtomicInteger(0);
public void handleRequest() {
int current = requestCount.incrementAndGet(); // 线程安全自增
if (current % 1000 == 0) {
System.out.println("已处理 " + current + " 次请求");
}
}
多个线程并发调用 handleRequest(),requestCount 的值绝不会丢失或重复计数——这就是无锁原子性的实际价值。
注意事项
- 单个
AtomicInteger方法是原子的,但**复合操作仍需同步**。例如:if (ai.get() 不是原子的,可能引发竞态,应改用 <code>ai.accumulateAndGet(1, Math::max)或配合循环 CAS 手动实现 - 高竞争场景下,CAS 失败会重试,可能带来一定 CPU 开销,但通常远优于锁的上下文切换成本
- 它只保证自身变量的原子性,不能替代对其他共享状态的整体同步
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











