溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

CAS原理與JDK8的優(yōu)化是什么

發(fā)布時間:2021-10-22 08:18:55 來源:億速云 閱讀:157 作者:柒染 欄目:大數(shù)據(jù)

CAS原理與JDK8的優(yōu)化是什么,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

什么是CAS

CAS-CompareAndSet,是JDK原子變量類AtomicInteger、AtomicLong、AtomicInteger、AtomicBoolean、AtomicReference等實現(xiàn)的基礎,例如對于一個共享變量int,就算是簡單的自增操作也不是原子性的,多線程同時自增,可能會導致變量的值比預期結果小。但是可以使用AtomicInteger的incrementAndGet() 方法操作變量,這樣結果和預期值一樣。跟傳統(tǒng)的加鎖不同,getAndDecrement()方法并沒有給代碼加鎖。代碼類似于:

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

底層通過sun.misc.Unsafe的本地方法compareAndSwapInt實現(xiàn),這個方法是原子的。

與synchronized的對比

  • 樂觀鎖與悲觀鎖的區(qū)別

  • 性能對比

synchronized是阻塞的,CAS更新是非阻塞的,只是會重試,不會有線程上下文切換開銷,對于大部分比較簡單的操作,無論是在低并發(fā)還是高并發(fā)情況下,這種樂觀非阻塞方式的性能都要遠高于悲觀阻塞式方式。

應用場景

  • 用來實現(xiàn)樂觀非阻塞算法,確保當前線程方法體內(nèi)使用的共享變量不被其他線程改變,CAS廣泛運用在非阻塞容器中。

  • 用來實現(xiàn)悲觀阻塞式算法,其用在了顯式鎖的原理實現(xiàn),如可重入計數(shù)中,調用lock()方法時將通過CAS方法將其設為1,調用unlock則設為遞減1。如果同時多個線程調用Lock方法那么必然會導致原子修改不成功,保證了鎖的機制,排他性。

可能存在的問題

  • ABA問題,普通的CAS操作并不是原子的,因為有可能另一個線程改了值但是又改回了值,那么樂觀鎖的方式是不能保證原子性的,若業(yè)務需要規(guī)避這種情況那么可以使用AtomicStampedReference的compareAndSet(V expectedReference, V newReference, int expectedStamp, int newStamp)方法,只有值和時間戳都相等的時候才進行原子更新,每次更新都把當前時間修改進原子變量。

JDK8的優(yōu)化

JAVA8新增了LongAdder、DoubleAdder對原子變量進行進一步優(yōu)化,主要是利用了分段CAS的機制,如果不用LongAdder,用AtomicLong的話,在高并發(fā)情況下,會產(chǎn)生一直自旋,導致效率不高。他將一個數(shù)分成若干個數(shù),CompareAndSet方法的參數(shù)只是比較的這若干個數(shù)中的一個數(shù),從而降低了自旋的概率,提高了效率。

關于CAS原理與JDK8的優(yōu)化是什么問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業(yè)資訊頻道了解更多相關知識。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI