Java CAS總結


 

文章目錄

 

1、 CPU指令對CAS的支持(CPU的cas指令是原子的)

      或許我們可能會有這樣的疑問,假設存在多個線程執行CAS操作並且CAS的步驟很多,有沒有可能在判斷V和E相同后,正要賦值時,切換了線程,更改了值。造成了數據不一致呢?答案是否定的,因為CAS是一種系統原語,原語屬於操作系統用語范疇,是由若干條指令組成的,用於完成某個功能的一個過程,並且原語的執行必須是連續的,在執行過程中不允許被中斷,也就是說CAS是一條CPU的原子指令,不會造成所謂的數據不一致問題。

 

2、 並發包中的原子操作類(Atomic系列)

  通過前面的分析我們已基本理解了無鎖CAS的原理並對Java中的指針類Unsafe類有了比較全面的認識,下面進一步分析CAS在Java中的應用,即並發包中的原子操作類(Atomic系列),從JDK 1.5開始提供了java.util.concurrent.atomic包,在該包中提供了許多基於CAS實現的原子操作類,用法方便,性能高效,主要分以下4種類型。

  可以發現AtomicInteger原子類的內部幾乎是基於前面分析過Unsafe類中的CAS相關操作的方法實現的,這也同時證明AtomicInteger是基於無鎖實現的,這里重點分析自增操作實現過程,其他方法自增實現原理一樣。

3、 CAS的ABA問題及其解決方案

  假設這樣一種場景,當第一個線程執行CAS(V,E,U)操作,在獲取到當前變量V,准備修改為新值U前,另外兩個線程已連續修改了兩次變量V的值,使得該值又恢復為舊值,這樣的話,我們就無法正確判斷這個變量是否已被修改過,如下圖

這就是典型的CAS的ABA問題,一般情況這種情況發現的概率比較小,可能發生了也不會造成什么問題,比如說我們對某個做加減法,不關心數字的過程,那么發生ABA問題也沒啥關系。但是在某些情況下還是需要防止的,那么該如何解決呢?在Java中解決ABA問題,我們可以使用以下兩個原子類

AtomicStampedReference類

  • AtomicStampedReference原子類是一個帶有時間戳的對象引用,在每次修改后,AtomicStampedReference不僅會設置新值而且還會記錄更改的時間。當AtomicStampedReference設置對象值時,對象值以及時間戳都必須滿足期望值才能寫入成功,這也就解決了反復讀寫時,無法預知值是否已被修改的窘境

 

 

參考文章:

1、JAVA中的CAS

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM