Atomic 翻译成中文是原子的意思。在化学中,原子是构成一般物质的最小单位,是不可分割的。而在这里,Atomic 表示当前操作是不可中断的,即使是在多线程环境下执行,Atomic 类,是具有原子操作特征的类。
Java 的原子类都存放在并发包 java.util.concurrent.atomic
下,如下图所示。
JUC 原子类概览
基本类型
使用原子的方式更新基本类型
数组类型
使用原子的方式更新数组里的某个元素
引用类型
对象的属性修改类型
AtomicInteger 类常用方法
public final int get(); // 获取当前的值
public final int getAndSet(int newValue); // 获取当前的值,并设置新的值
public final int getAndIncrement(); // 获取当前的值,并自增
public final int getAndDecrement(); // 获取当前的值,并自减
public final int getAndAdd(int delta); // 获取当前的值,并加上预期的值
boolean compareAndSet(int expect, int update); // 如果输入的数值等于预期值,则以原子方式将该值设置为输入值(update)
public final void lazySet(int newValue); // 最终设置为 newValue,使用 lazySet 设置之后可能导致其他线程在之后的一小段时间内还是可以读到旧的值。
AtomicInteger 类使用示例
class AtomicIntegerTest {
private AtomicInteger count = new AtomicInteger();
public void increment() {
// 使用 AtomicInteger 之后,不用对 `increment()` 方法加锁也可以保证线程安全
count.incrementAndGet();
}
public int getCount() {
return count.get();
}
}
以 AtomicInteger 类为例,以下是部分源代码:
// setup to use Unsafe. compareAndSwapInt for updates(更新操作时提供“比较并替换”的作用)
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
private volatile int value;
AtomicInteger 类利用 CAS (Compare and Swap) + volatile + native
方法来保证原子操作,从而避免 synchronized 的高开销,执行效率大为提升。
CAS 的原理,是拿期望值和原本的值作比较,如果相同,则更新成新的值。UnSafe 类的 objectFieldOffset() 方法是个本地方法,这个方法是用来拿“原值”的内存地址,返回值是 valueOffset;另外,value 是一个 volatile 变量,因此 JVM 总是可以保证任意时刻的任何线程总能拿到该变量的最新值。