ABA问题怎么解:AtomicStampedReference和AtomicMarkableReference
程序员文章站
2023-09-28 18:57:49
本博客系列是学习并发编程过程中的记录总结。由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅。 "并发编程系列博客传送门" "并发编程的基石——CAS机制" 这篇文章中介绍到CAS机制有一个缺点就是ABA问题:CAS在操作的时候会检查变量的值是否被更改过,如果没有则更新值,但 ......
本博客系列是学习并发编程过程中的记录总结。由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅。
并发编程的基石——cas机制这篇文章中介绍到cas机制有一个缺点就是aba问题:cas在操作的时候会检查变量的值是否被更改过,如果没有则更新值,但是带来一个问题是:如果值最开始的值是a,接着变成b,最后又变成了a。经过检查这个值确实没有修改过,因此cas机制会更新这个值。但是实际上这个值已经被修改过了。
atomicstampedreference
和atomicmarkablereference
就是用来解决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,表示此引用未被标记。