原子操作
原子操作:Java 并发安全的基石
在多线程环境中,对共享变量的操作若不加以控制,可能导致数据不一致(如i++这类看似原子的操作,实际包含 “读取 - 修改 - 写入” 三步)。Java 的java.util.concurrent.atomic包提供了一系列原子操作类,通过底层的 CAS(Compare-And-Swap)机制,确保操作的原子性,避免线程安全问题。
原子操作类的核心原理
原子操作类的本质是通过Unsafe 类实现的 CAS 操作,其核心思想是:乐观锁—— 假设操作不会冲突,若冲突则重试,直到成功。以最常用的AtomicInteger为例,其内部通过volatile修饰的value存储值,并借助 Unsafe 的 native 方法实现原子更新。
AtomicInteger 的核心源码解析
public class AtomicInteger extends Number implements java.io.Serializable {
private static final long serialVersionUID = 6214790243416807050L;
// 用于执行底层CAS操作的Unsafe实例
private static final Unsafe unsafe = Unsafe.getUnsafe();
// value字段在对象中的内存偏移量(用于CAS定位)
private static final long valueOffset;
static {
try {
// 获取value字段的内存偏移量
valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) {
throw new Error(ex);
}
}
// 存储实际值,用volatile保证可见性
private volatile int value;
// 核心方法解析:
// 1. 获取当前值(volatile保证可见性)
public final int get() {
return value;
}
// 2. 原子更新:若当前值等于预期值,则更新为新值
public final boolean compareAndSet(int expect, int update) {
// 调用Unsafe的CAS方法,原子性地比较并替换
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
// 3. 原子自增(i++的线程安全版)
public final int getAndIncrement() {
// 先获取当前值,再加1(底层通过循环CAS实现)
return unsafe.getAndAddInt(this, valueOffset, 1);
}
// 4. 原子自增(++i的线程安全版)
public final int incrementAndGet() {
// 先加1,再返回新值
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
// 其他方法:getAndDecrement()、decrementAndGet()、getAndAdd()等原理类似
}
CAS 操作的底层逻辑
unsafe.compareAndSwapInt(this, valueOffset, expect, update)的工作流程:
