認識CAS自旋


概念

  比較並交換,簡單來說,預期值與內存的值比較,相等則更新,否則循環下去

理解

  內存里存的一個值,你拿去,在更新的時候調用,如果這期間沒人動過這個值,你可以更新,

否則,重復操作,直至成功。

  對一個值自增的自旋操作,偽代碼如下:

  

public final int getAndIncrement() {
                 for (;;) {
                       int current = get();  // 取得內存里數值
                     int next = current + 1;  // 加1
                     if (compareAndSet(current, next))   // 調用compareAndSet執行原子更新操作
                         return current;
                 }
             }

結合例子

黑盒,存一個數字i,初始為0


線程A,B,C

線程A,

  第一次自旋:去黑盒拿一個數字,假設這時候為0,B和C拿到值為0,還未更新i值,A更新是(expect:0, update:1),執行成功,此時黑盒里i為1

線程B,
  第一次自旋:執行(expect:0, update:1),因為這時候被A更新為1了,所以失敗,
  第二次自旋:再去拿值,這時候拿到的是1,假設這時候C還未更新,執行(expect:1,update:2),更新成功,此時黑盒里i為2
線程C,
  第一次自旋失敗,原因如B
  第二次自旋:因為被B搶先了,所以也失敗
  第三次自旋:拿到的值為2,執行(expect:2,update:3),成功

總結

  自旋的意思,多個線程奪取鎖,那就必須先讓自己得到的值跟內存的值一樣才能操作

ABA問題

  線程A拿到的值是X,但X有可能被另一個線程B改為Y,又改為X,線程A這種情況下視為沒有發生過變化,其實變化了,對此,AtomicStampedReference 

提供了依據版本號判斷變化的實現。


免責聲明!

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



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