
在Java并发编程中,AtomicInteger 是一个非常实用的原子类,用于解决多线程环境下整数操作的线程安全问题。相比使用 synchronized 关键字,AtomicInteger 利用底层的 CAS(Compare-And-Swap)机制实现无锁并发,性能更高,使用也更灵活。
1. 原子类的核心优势:无锁高效并发
AtomicInteger 的核心是基于 volatile 和 Unsafe 类提供的 CAS 操作。它保证了对整数变量的读-改-写操作是原子的,比如自增、自减、加指定值等。
常见应用场景包括计数器、状态标志、序列号生成等需要高并发读写的场景。
- CAS 避免了线程阻塞,提升吞吐量
- 比 synchronized 更轻量,适合细粒度同步
- 适用于竞争不极端激烈的场景(高竞争下可能引发自旋开销)
2. 常用方法与使用技巧
掌握 AtomicInteger 的关键 API 能大幅提升代码的简洁性和可靠性。
立即学习“Java免费学习笔记(深入)”;
incrementAndGet()原子性地将当前值加1并返回新值,等价于 ++i。
适合做计数器递增:
AtomicInteger counter = new AtomicInteger(0); int newValue = counter.incrementAndGet(); // 线程安全的 ++igetAndIncrement()
先返回当前值,再加1,等价于 i++。注意返回的是旧值。
如果需要判断原始值,应使用此方法:
int oldValue = counter.getAndIncrement();compareAndSet(expected, newValue)
这是实现乐观锁的基础。只有当前值等于预期值时才更新为新值,返回是否成功。
可用于实现重试机制或状态切换:
while (!counter.compareAndSet(expected, expected + 1)) {
expected = counter.get(); // 重新读取最新值
}
addAndGet(delta)
原子性地增加指定增量,支持负数(相当于减)。
counter.addAndGet(5); // 加5 counter.addAndGet(-3); // 减3
3. 注意事项与最佳实践
虽然 AtomicInteger 使用简单,但仍有几个关键点需要注意。
- 只保证单个操作的原子性,多个操作组合仍需额外同步
- 避免过度使用,低并发场景下普通 int + synchronized 可能更清晰
- 不要依赖 get() 方法的“实时性”,其值可能在调用瞬间已过期
- 在高竞争场景中,CAS 失败率上升,可能导致 CPU 自旋消耗,可考虑使用 LongAdder 替代
例如:先判断再更新的操作(if-then-put)不是原子的,必须用循环 + compareAndSet 实现。
4. 实际应用示例:限流计数器
利用 AtomicInteger 实现简单的接口调用限流:
AtomicInteger requestCount = new AtomicInteger(0);
int MAX_REQUESTS = 100;
public boolean tryExecute() {
int current;
do {
current = requestCount.get();
if (current >= MAX_REQUESTS) {
return false; // 超过限制
}
} while (!requestCount.compareAndSet(current, current + 1));
return true;
}
这个例子展示了如何用 CAS 实现无锁的条件更新,避免竞态条件。
基本上就这些。AtomicInteger 是并发工具箱中的基础但强大的组件,理解其原理和正确使用方式,能有效提升多线程程序的性能与稳定性。










