Java CAS簡單說明

如果懂JMM,這個壓根就不用看。

CAS(Compare And Swap)

其保留有3個值 V(內(nèi)存值)、A(舊的預期值/舊值)、B(要修改的值/新值)
V指的是主存中的存在的值;A指的是每個線程自己持有的V的副本;B是經(jīng)過一系列自己指定的運算后的結(jié)果。
當且僅當預期值A(chǔ)和內(nèi)存值V相同時,將內(nèi)存值修改為B并返回true,否則什么都不做并返回false

設(shè)定:
1.內(nèi)存中有個空間(Q)存儲了一個值為1,我們使用多線程且使用CAS進行修改會發(fā)生如下反應。
2.有2個線程(A和B)同時對Q進行 +1 操作。(可以參考JDK 1.7中AtomicInteger)

// JDK 1.7 中的代碼示例

private volatile int value;
private static final Unsafe unsafe = Unsafe.getUnsafe();

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

public final int get() {
    return value;
}

public final boolean compareAndSet(int expect, int update) {
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
根據(jù)JMM可以得知,2個線程會各自獲取一份Q的副本(值為1)。
1.線程A開始運行,current獲取到線程中的副本值為1,然后執(zhí)行完成+1操作,此時線程切換給B操作。
2.線程B開始運行,current獲取到線程中的副本值為1,然后執(zhí)行完成+1操作,`之后拿著線程B中Q的副本[current]與Q的值進行比較,如果兩值相等就將計算出來的next進行替換掉Q的原值(CAS操作)`,此時線程切換給A操作。
3.線程A開始運行,拿著線程A中Q的副本進行相同的比較與賦值操作(CAS操作),在V與A的比較中發(fā)現(xiàn)不對等(**內(nèi)存中的Q值為2,線程B的副本值為1**),于是認為value正在被另外一個線程操作,所以不能進行值替換。**
4.這個時候線程A會再一次取Q中的值作為新的副本,再次進行+1操作并通過CAS嘗試寫入新值,如果一直寫不進去這個過程會不斷重復,直到能成功的執(zhí)行為止。

根據(jù)代碼可以看出這個valuevolatile修飾符十分重要,當操作失敗后能及時的獲取到其他線程對其的修改值。
如果去掉volatile修飾符,那不同線程之間就完全感知不到對方對值的修改,也就是說在第4步的時候,線程A永遠取不到Q的新值。

至于compareAndSet方法,我們也能從示例代碼中清楚的看到是調(diào)用了Unsafe這個類中的方法。
Unsafe提供了硬件級別的原子操作,但不建議自己使用。

CAS的ABA問題

在上訴基礎(chǔ)上,多添加幾個線程進行對Q的操作,要求是加減都有。
那線程中CAS操作會不會存在問題?
線程L的副本存儲的為1,我們不能確保在線程L中進行V和A的比較操作之前,是否有其他線程將Q的值改為2后又改回了1。
這就是ABA問題,當然可以采用版本號等方式解決。

ABA問題的例子:
主存中的V的值為1。
線程A中副本值為1,然后進行+1操作,線程切換。
線程B中的副本之為1,然后進行+1操作,最后通過CAS對V的值進行寫入,現(xiàn)在V的值為2,線程切換。
線程C中的副本之為2,然后進行-1操作,最后通過CAS對V的值進行寫入,現(xiàn)在V的值為1,線程切換。
線程A之前已經(jīng)計算完了,現(xiàn)在嘗試進行用CAS操作,發(fā)現(xiàn)V和自己的副本值相同后進行寫入操作。

雖然看起來沒什么問題,但可能在某些邏輯中就會導致潛在問題的出現(xiàn)。

額外補充

觀看其他的java.util.concurrent中的代碼不難發(fā)現(xiàn),該包是基于CAS的構(gòu)建的,而CAS又依賴于Unsafe類。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容