在 java.util.concurrent.atomic 包中,Atomic 打頭的原子操作類有很多。涉及到 Java 常用的數位型別的,基本都有相應的 Atomic 原子操作類,如下圖所示:
Atomic 打頭的原子操作類,在高並行場景下,都是執行緒安全的,我們可以放心使用。
主要是呼叫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 實現的,都是執行緒安全的。
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;
}