AtomicInteger 笔记

一、什么是 AtomicInteger?

AtomicInteger 是 Java 并发包(java.util.concurrent.atomic)中的原子类,用于在 多线程环境下安全地进行整数的原子操作(如自增、自减、赋值等),避免了使用 synchronized 锁的性能开销。

二、核心作用

解决多线程对整数变量进行 复合操作(如 i++i = i + 2)时的线程安全问题

  • 普通 int 的 i++ 是 “读 - 改 - 写” 三步操作,非原子性,多线程并发时会导致结果错误;
  • AtomicInteger 通过 CAS 机制 保证这些操作的原子性(一步完成,不可打断)。

三、底层实现:CAS 机制

CAS(Compare-And-Swap,比较并交换)是一种无锁同步技术,核心逻辑:

  1. 读取变量当前值(expectedValue);
  2. 计算目标值(newValue);
  3. 若当前值仍为 expectedValue(未被其他线程修改),则更新为 newValue;否则重试(自旋),直到成功。

AtomicInteger 内部通过 volatile int value 存储值(保证可见性),配合 CAS 完成原子操作。

四、常用方法

方法名 功能描述 示例(初始值为 5)
get() 获取当前值 get() → 5
set(int newValue) 设置为新值(直接覆盖) set(10) → 后续 get() 为 10
getAndIncrement() 先返回当前值,再自增 1 getAndIncrement() → 返回 5,值变为 6
incrementAndGet() 先自增 1,再返回新值 incrementAndGet() → 返回 6,值变为 6
getAndDecrement() 先返回当前值,再自减 1 getAndDecrement() → 返回 5,值变为 4
decrementAndGet() 先自减 1,再返回新值 decrementAndGet() → 返回 4,值变为 4
getAndAdd(int delta) 先返回当前值,再加 delta getAndAdd(3) → 返回 5,值变为 8
addAndGet(int delta) 先加 delta,再返回新值 addAndGet(3) → 返回 8,值变为 8
compareAndSet(int expect, int update) 若当前值等于 expect,则更新为 update,返回是否成功 compareAndSet(5, 10) → 返回 true,值变为 10

五、使用场景

  1. 多线程计数:如统计请求量、下载进度等(替代 synchronized 修饰的计数逻辑)。
1
2
3
4
5
6
7
8
9
// 30个线程各自增10000次,结果一定是300000
AtomicInteger sum = new AtomicInteger();
for (int i = 0; i < 30; i++) {
new Thread(() -> {
for (int j = 0; j < 10000; j++) {
sum.incrementAndGet(); // 原子自增
}
}).start();
}
  1. 线程安全的状态标记:如用 compareAndSet 实现无锁的状态更新。
1
2
3
AtomicInteger state = new AtomicInteger(0); // 0:初始,1:运行,2:结束
// 只有当状态为0时,才更新为1(避免重复启动)
boolean started = state.compareAndSet(0, 1);

六、优缺点

  • 优点

    性能优于 synchronized(无锁机制,减少线程阻塞 / 唤醒开销),适合高并发场景。

  • 缺点

    1. 仅支持整数类型(其他原子类如 AtomicLongAtomicBoolean 可覆盖其他基本类型);
    2. 复合操作(如 i = i * 2 + 1)无法直接保证原子性,需配合 compareAndSet 循环实现;
    3. 高并发下 CAS 自旋可能导致 CPU 消耗较高。

七、总结

  • AtomicInteger 是多线程环境下安全操作整数的首选工具,基于 CAS 实现原子性。
  • 核心优势:高效解决简单整数操作的线程安全问题,性能优于传统锁。
  • 适用场景:计数、状态标记等简单原子操作,复杂逻辑需结合其他同步工具。