ABA問題怎么解:AtomicStampedReference和AtomicMarkableReference



本博客系列是學習並發編程過程中的記錄總結。由於文章比較多,寫的時間也比較散,所以我整理了個目錄貼(傳送門),方便查閱。

並發編程系列博客傳送門


並發編程的基石——CAS機制這篇文章中介紹到CAS機制有一個缺點就是ABA問題:CAS在操作的時候會檢查變量的值是否被更改過,如果沒有則更新值,但是帶來一個問題是:如果值最開始的值是A,接着變成B,最后又變成了A。經過檢查這個值確實沒有修改過,因此CAS機制會更新這個值。但是實際上這個值已經被修改過了。

AtomicStampedReferenceAtomicMarkableReference就是用來解決CAS中的ABA問題的。他們解決ABA問題的原理類似,都是通過一個版本號來區分有沒被更新過。

  • AtomicStampedReference:帶版本戳的原子引用類型,版本戳為int類型。
  • AtomicMarkableReference:帶版本戳的原子引用類型,版本戳為boolean類型。

AtomicStampedReference使用列子

public class AtomicStampedReferenceDemo {

    private static Long var = new Long(1);

    public static void main(String[] args) {
        AtomicStampedReference<Long> referenceDemo = new AtomicStampedReference(var,1);
        System.out.println("now value:"+referenceDemo.getReference().intValue());
        int stamp = referenceDemo.getStamp();
        System.out.println("now stamp:"+stamp);
        boolean b = referenceDemo.compareAndSet(var, new Long(2), stamp, stamp + 1);
        if(b){
            System.out.println("success set value...");
            System.out.println("now value:"+referenceDemo.getReference().intValue());
            stamp = referenceDemo.getStamp();
            System.out.println("now stamp:"+stamp);
        }else {
            System.out.println("failed set value...");
            System.out.println("now value:"+referenceDemo.getReference().intValue());
            stamp = referenceDemo.getStamp();
            System.out.println("now stamp:"+stamp);
        }
    }

}

AtomicMarkableReference使用

關於AtomicMarkableReference的原理其實是與AtomicStampedReference類似的。

區別是AtomicMarkableReference的版本戳是boolean類型,所以導致版本狀態只有兩個:true或者false。

所以,我更傾向於稱呼AtomicMarkableReference為帶標記的原子引用類型。

  • 版本戳 = true,表示此引用被標記。
  • 版本戳 = false,表示此引用未被標記。


免責聲明!

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



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