CAS-一看就懂了點

單同志發表於2019-08-20

介紹

CAS:Compare and Swap,比較並交換。對於併發,鎖是一種悲觀策略,會阻塞執行緒執行。科技發展,自然而然就會渴求樂觀策略,無鎖就是一種概念上的體現。對於無鎖的一種技術支援就是CAS。

閱讀

目前我所見到的對CAS的使用,都是通過Unsafe類支援的。CAS有3個運算元V(記憶體值,真正的共享的記憶體值,不是快取中的),A(期待值或者說快取中的值),B(修改的新值)。我們以AtomicInteger的compareAndSet方法來讓我們對3個運算元有個具象化的瞭解(核心也就是了解這3個運算元)。

compareAndSet

public final boolean compareAndSet(int expect, int update) {
        // U就是Unsafe類
        // private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
        return U.compareAndSwapInt(this, VALUE, expect, update);
    }
複製程式碼

Unsafe類的compareAndSwapInt的實現是native的,就是C++的實現。它是一個原子操作。他的原子性就是通過CAS這麼個原子指令實現的,由處理器保證。如果你想有更多瞭解,點這裡

  • VALUE 即CAS中的V。他是如何獲取的呢?
static {
        try {
            // 你看,還是Unsafe類提供的方法。配合反射拿到value Field對應的實際記憶體中的值
            VALUE = U.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (ReflectiveOperationException e) {
            throw new Error(e);
        }
    }
複製程式碼
  • expect 即CAS中的A
// value 即A 使用volatile保證其執行緒可見性
private volatile int value;
// 通過此方法獲取value
public final int get() {
        return value;
    }
複製程式碼
  • update 即CAS中的B 通常新值是通過函數語言程式設計形式提供的函式計算出來的
public final int getAndUpdate(IntUnaryOperator updateFunction) {
        int prev, next;
        do {
            prev = get();
            next = updateFunction.applyAsInt(prev);
        } while (!compareAndSet(prev, next));//注意這個迴圈條件,CAS操作失敗控制繼續嘗試
        return prev;
    }
複製程式碼

相信,到這裡,我們隊CAS也就有一個大概印象了。本文暫且也就到這裡~

相關文章