LinkedBlockingQueue 等並發容器大量使用 AtomicInteger 維護計數器。傳統 synchronized 屬於悲觀鎖:假設衝突必發,線程阻塞/喚醒開銷大;若臨界區極短(如計數器++),上下文切換成本遠超業務邏輯。
CAS (Compare-And-Swap) 是樂觀鎖的硬件級實現,三個操作數:
V:內存值A:預期值B:新值原子操作:若 V == A,則 V = B,返回 true;否則不修改,返回 false。失敗線程不阻塞,自旋重試(for(;;))。
場景:V 從 A→B→A,CAS 以為未變。解決:引入版本號或時間戳,即 AtomicStampedReference,比較 (引用, 版本) 對。
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
非線程安全的 get() + 加法,但 compareAndSet 保證原子性更新。
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
unsafe:sun.misc.Unsafe,繞過 JVM 安全檢查直接操作內存。valueOffset:value 字段在對象中的內存偏移量(靜態初始化獲取)。compareAndSwapInt:Native 方法,映射 CPU CMPXCHG 指令(x86 鎖總線/緩存行)。
// 非真實 CAS,僅示意邏輯
class SimpleCAS {
private volatile int value; // volatile 保證可見性
public synchronized boolean compareAndSwap(int expected, int newValue) {
int old = value;
if (old == expected) { value = newValue; return true; }
return false;
}
}
class CASCounter {
private SimpleCAS cas;
public int increment() {
int old = cas.getValue();
for (;;) if (cas.compareAndSwap(old, old+1)) return cas.getValue();
}
}
真實 AtomicInteger 無 synchronized,完全依賴 Unsafe + volatile 實現無阻塞(非無等待)線程安全。
LongAdder(分段計數)或鎖。