欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ABA问题怎么解:AtomicStampedReference和AtomicMarkableReference

程序员文章站 2023-09-28 18:57:49
本博客系列是学习并发编程过程中的记录总结。由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅。 "并发编程系列博客传送门" "并发编程的基石——CAS机制" 这篇文章中介绍到CAS机制有一个缺点就是ABA问题:CAS在操作的时候会检查变量的值是否被更改过,如果没有则更新值,但 ......

本博客系列是学习并发编程过程中的记录总结。由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅。


并发编程的基石——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,表示此引用未被标记。