atomicinteger通过cas实现无锁线程安全计数,比int(非原子)和synchronized(有锁开销)更高效;常用方法包括incrementandget、compareandset等,适用于简单计数但需注意溢出和复合操作原子性。

在 Java 并发编程中,AtomicInteger 是实现线程安全计数最常用、最轻量的方式之一。它通过底层的 CAS(Compare-and-Swap)指令保证操作的原子性,无需加锁,性能高且代码简洁。
为什么不用 int 或 synchronized?
普通 int 变量在多线程下 ++ 操作不是原子的(读取、加 1、写回三步),会导致数据丢失;而用 synchronized 虽能保证安全,但带来锁开销和阻塞风险。AtomicInteger 在大多数场景下更高效、更直观。
核心用法:初始化与常用方法
创建后即可直接调用原子方法,所有操作都线程安全:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
-
new AtomicInteger(0):指定初始值,不传则默认为 0 -
incrementAndGet():自增并返回新值(等价于 ++i) -
getAndIncrement():返回当前值,再自增(等价于 i++) -
compareAndSet(expected, updated):仅当当前值等于 expected 时,才设为 updated,返回是否成功——这是 CAS 的直接体现 -
addAndGet(delta):加指定值并返回结果,支持任意增量
典型使用示例
比如统计某接口的总调用次数:
public class CounterService {
private final AtomicInteger totalCount = new AtomicInteger(0);
public void recordRequest() {
totalCount.incrementAndGet(); // 线程安全,无锁
}
public int getCurrentCount() {
return totalCount.get(); // get() 也是原子读
}
}
多个线程并发调用 recordRequest(),不会出现计数错误。如果需要“仅首次调用才执行某逻辑”,可结合 compareAndSet(0, 1) 实现一次性初始化。
注意事项与边界情况
AtomicInteger 适合简单计数或状态标记,但不适用于复杂业务逻辑的原子组合操作。例如,“先判断再更新”若拆成两次调用(如 if (get() > 10) set(0)),就不是原子的,此时应考虑 AtomicInteger.updateAndGet() 或 getAndUpdate()(Java 8+),它们在一个 CAS 循环中完成读-改-写:
-
updateAndGet(unaryOperator):传入一个函数,如i -> i > 10 ? 0 : i + 1 -
注意溢出:它不检查整数溢出,
incrementAndGet()到Integer.MAX_VALUE后会变成Integer.MIN_VALUE,如需防溢出,得自行判断或改用AtomicLong配合Math.addExact
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










