CAS核心思想、底層實現

語言: CN / TW / HK

★ 1、CAS 是什麼

CAS 是比較並交換,是實現併發演算法時常用到的一種技術。 當記憶體的值和期望的值相等時,進行更新 ,否則 什麼都不做 重來

CAS 的底層實現:是靠硬體實現的,靠硬體的原子性實現, CAS是一條CPU的原子指令 cmpxchg指令 ), 不會造成所謂的資料不一致問題

重來==> 自旋

CAS 類似樂觀鎖,樂觀的認為別人沒有修改,當值還是預期值,就進行修改,否則可能什麼都不做,或者重來。

★ 2、CAS 應用舉例

  • 原子操作類,比如整型的原子操作類的compareAndSet方法
  • 我的部落格專案中,在更新文章瀏覽次數時,當前 記憶體的文章瀏覽次數 和 期望中的 資料庫的文章瀏覽次數 進行比較,如果是相同的,則加1,否則 什麼都不做

3、原子類

■ 原子類==> 底層思想/工作原理 CAS ==> Unsafe 類的CPU 原語級別的彙編操作

  • CAS 是靠硬體實現的,靠硬體的原子性實現 , CAS是一條CPU的原子指令 cmpxchg指令 ), 不會造成所謂的資料不一致問題

    Unsafe提供的CAS方法(如compareAndSwapXXX)底層實現即為CPU指令cmpxchg。

■ AtomicInteger 類主要利用 CAS + volatile 和 native 方法來 保證原子操作,從而避免 synchronized 的高開銷 ,執行效率大為提升。

new AtomicInteger().compareAndSet(0, 1);

// 底層實現
public final int getAndAdd(int delta) {
 return unsafe.getAndAddInt(this, valueOffset, delta);
}
public final boolean compareAndSet(int expect, int update) {
 return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}



new AtomicInteger().getAndAdd(1);//獲取到當前值並加1
// 底層實現
public final int getAndAdd(int delta) {
return unsafe.getAndAddInt(this, valueOffset, delta);
}
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
   var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
return var5;
}

■ 工作中,不建議使用Unsafe 類,類名就提示你了"不安全"!

4、Unsafe 類

  • 是CAS的核心類
  • 可以 像C的指標一樣直接操作記憶體
  • Unsafe類中的所有方法都是native修飾的 Unsafe類中的方法都可以直接呼叫作業系統底層資源去執行相應任務
//原子類
public final int getAndIncrement() {
     return unsafe.getAndAddInt(this, valueOffset, 1);
}

private volatile int value;

變數 valueOffset ,表示該變數值在記憶體中的 偏移地址 ,因為 Unsafe就是根據記憶體偏移地址獲取資料 的。

變數value用volatile修飾,保證了多執行緒之間的記憶體可見性。每次獲取的值都是最新的。

5、CAS 帶來的問題

  • 迴圈時間長,可能死迴圈,開銷很大
  • ABA 問題
    • 解決ABA 問題: 帶版本號的原子引用 AtomicStampedReference

如果本文對你有幫助的話記得給一樂點個贊哦,感謝!