AtomicInteger
和 volatile Integer
虽然都与线程安全有关,但本质完全不同。它们的主要区别体现在原子性保证和功能上:
特性 | volatile Integer |
AtomicInteger |
---|---|---|
原子性 | ❌ 不保证复合操作原子性 | ✅ 保证所有操作的原子性 |
自增操作安全性 | ❌ i++ 不安全 |
✅ incrementAndGet() 安全 |
CAS 操作 | ❌ 不支持 | ✅ 原生支持 compareAndSet() |
函数式更新 | ❌ 不支持 | ✅ 支持 updateAndGet() |
性能表现 | 简单读写快 | 复合操作远优于锁同步 |
内部原理 | 内存屏障 + 禁止重排序 | volatile + CAS 自旋 |
public class VolatileCounter {
private volatile Integer count = 0;
// 线程不安全的操作!
public void increment() {
count++; // 实际分为三步: 读 -> 改 -> 写
}
public int getCount() {
return count;
}
}
问题代码解释:
count=0
count=0
0+1=1
写入0+1=1
写入import java.util.concurrent.atomic.AtomicInteger;
public class SafeCounter {
private final AtomicInteger count = new AtomicInteger(0);
// 线程安全操作
public void safeIncrement() {
count.incrementAndGet(); // 原子操作
}
public int getCount() {
return count.get();
}
}
关键原理:
// AtomicInteger 内部实现原理
public final int incrementAndGet() {
return U.getAndAddInt(this, VALUE, 1) + 1;
}
// 实际执行(Unsafe类):
public final int getAndAddInt(Object o, long offset, int delta) {
int v;
do {
v = getIntVolatile(o, offset); // 1. 读取volatile值
} while (!weakCompareAndSetInt(v, v + delta)); // 2. CAS自旋
return v;
}
volatile 的作用
AtomicInteger 的优势
性能对比场景
// 测试代码片段
for(int i=0; i<1000000; i++) {
// volatile版:1000ms+
// AtomicInteger版:200ms
}
volatile int value (基本保障)
│
▼
+-----------------+
| AtomicInteger |→ CAS保证复合操作原子性
| (封装增强) |→ 提供原子操作方法族
+-----------------+
可见
AtomicInteger
内部使用 volatile 保证可见性(通过private volatile int value
字段),但增加了 CAS 机制来实现更复杂的原子操作,这是单纯 volatile 做不到的。
AtomicInteger/Long/Boolean
volatile
AtomicReference
LongAdder