在 java.util.concurrent.atomic 包中,Atomic 打头的原子操作类有很多。涉及到 Java 常用的数字类型的,基本都有相应的 Atomic 原子操作类,如下图所示:
Atomic 打头的原子操作类,在高并发场景下,都是线程安全的,我们可以放心使用。
1.AtomicInteger
主要是调用Unsafe类的CAS操作,下面是 AtomicInteger 的部分源码:
public class AtomicInteger extends Number implements java.io.Serializable {
// 注:value是被volatile修饰的
private volatile int value;
// 初始化
public AtomicInteger(int initialValue) {
value = initialValue;
}
// 得到当前值
public final int get() {
return value;
}
// 自增 1,并返回自增之前的值
public final int getAndIncrement() {
return unsafe.getAndAddInt(this, valueOffset, 1);
}
// 自减 1,并返回自增之前的值
public final int getAndDecrement() {
return unsafe.getAndAddInt(this, valueOffset, -1);
}
}
从源码中,我们可以看到,线程安全的操作方法,底层都是使用 unsafe 方法实现,以上几个 unsafe 方法不是使用 Java 实现的,都是线程安全的。
2.AtomicReference
AtomicInteger 是对 int 类型的值进行自增自减,那如果 Atomic 的对象是个自定义类怎么办呢,Java 也提供了自定义对象的原子操作类,叫做 AtomicReference。AtomicReference 类可操作的对象是个泛型,所以支持自定义类,其底层是没有自增方法的,操作的方法可以作为函数入参传递,源码如下:
// 对 x 执行 accumulatorFunction 操作
// accumulatorFunction 是个函数,可以自定义想做的事情
// 返回老值
public final V getAndAccumulate(V x,BinaryOperator<V> accumulatorFunction) {
// prev 是老值,next 是新值
V prev, next;
// 自旋 + CAS 保证一定可以替换老值
do {
prev = get();
// 执行自定义操作
next = accumulatorFunction.apply(prev, x);
} while (!compareAndSet(prev, next));
return prev;
}