續《java.util.concurrent 包結構概覽》,本文深入剖析 atomic 包核心實現:CAS 原理、Unsafe 基石、四大基本類型、數組原子類、FieldUpdater、帶標記引用等進階組件。
無鎖並發原語,三元操作:(V, A, B) → 如果 V==A 則 V=B 返回 true,否則返回 false。
LOCK CMPXCHG)AtomicStampedReference)JVM 內部類,提供「越過 Java 安全檢查」的底層能力:
allocateMemory/freeMemory)objectFieldOffset)compareAndSwapInt/Long/Object)loadFence/storeFence/fullFence)所有 atomic 類最終委託 Unsafe 實現原子操作。
| 類 | 底層類型 | 核心字段 | 適用場景 |
|---|---|---|---|
| AtomicInteger | int | volatile int value | 計數器、序列號、狀態標記 |
| AtomicLong | long | volatile long value | 高併發 ID 生成、時間戳、統計聚合 |
| AtomicBoolean | int (0/1) | volatile int value | 開關標誌、一次性初始化鎖 |
| AtomicReference<V> | Object | volatile V value | 無鎖單例、引用交換、不可變對象更新 |
// 獲取/設置
get() / set(newValue)
// CAS 更新
compareAndSet(expect, update) // 強一致性
weakCompareAndSet(expect, update) // 弱一致性,允許虛假失敗(性能優)
// 無條件設置(有序性語義)
lazySet(newValue) // 釋放語義,不保證立即可見
// 獲取並更新(原子複合操作)
getAndSet(newValue)
getAndIncrement() / incrementAndGet()
getAndAdd(delta) / addAndGet(delta)
AtomicIntegerArray、AtomicLongArray、AtomicReferenceArrayAtomicBooleanArray(可用 IntegerArray 代替)volatile 修飾數組引用無意義,需 Unsafe 逐元素操作index 參數:getAndIncrement(int i)
// 靜態工廠獲取 Updater
AtomicIntegerFieldUpdater updater =
AtomicIntegerFieldUpdater.newUpdater(User.class, "age");
// 目標字段要求:
// 1. volatile 修飾
// 2. 類型匹配(Integer/Long/Object)
// 3. 非 static
// 使用
updater.getAndIncrement(user); // 原子更新 user.age
門面模式:抽象類 + 私有實現類,newUpdater() 返回具體實例。
| 類 | Pair 結構 | 用途 |
|---|---|---|
| AtomicMarkableReference<V> | <V, Boolean> | 邏輯刪除標記、狀態翻轉 |
| AtomicStampedReference<V> | <V, Integer> | 版本號、修訂計數、ABA 完全解決 |
內部封裝 AtomicReference<Pair>,CAS 同時比較引用與標記/版本。
AtomicLong.set() 非原子?實則視 JVM 是否支援 VM_SUPPORTS_LONG_CAS,不支援則退化為鎖weakCompareAndSet 可能虛假失敗,適用於計數器統計等容忟偶發重試場景lazySet 利用 Unsafe.putOrderedLong 實現釋放語義,比 volatile write 輕量