首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

AtomicInteger 源碼深度解析:CAS 無鎖機制、樂觀鎖與 ABA 問題

     編輯:Java 綜合教學

背景:為什麼需要 AtomicInteger?

LinkedBlockingQueue 等並發容器大量使用 AtomicInteger 維護計數器。傳統 synchronized 屬於悲觀鎖:假設衝突必發,線程阻塞/喚醒開銷大;若臨界區極短(如計數器++),上下文切換成本遠超業務邏輯。

樂觀鎖與 CAS 原理

CAS (Compare-And-Swap) 是樂觀鎖的硬件級實現,三個操作數:

  • V:內存值
  • A:預期值
  • B:新值

原子操作:若 V == A,則 V = B,返回 true;否則不修改,返回 false。失敗線程不阻塞,自旋重試(for(;;))。

ABA 問題及解決

場景:V 從 A→B→A,CAS 以為未變。解決:引入版本號或時間戳,即 AtomicStampedReference,比較 (引用, 版本) 對。

AtomicInteger 核心源碼解讀

getAndIncrement()

public final int getAndIncrement() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return current;
    }
}

非線程安全的 get() + 加法,但 compareAndSet 保證原子性更新。

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 實現計數器(教學用)


// 非真實 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 實現無阻塞(非無等待)線程安全。

性能與適用場景

  • 低/中競爭:CAS 自旋極快,吞吐遠超鎖。
  • 高競爭:大量線程自旋消耗 CPU,可考慮 LongAdder(分段計數)或鎖。
  • 適用於計數器、序列生成器、狀態標誌等簡單原子操作。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved