Loading

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,表示此引用未被标记。
posted @ 2020-01-14 11:24  程序员自由之路  阅读(1350)  评论(0编辑  收藏  举报