在运用CAS做Lock-Free操作中有一个经典的ABA问题:

线程1准备用CAS将变量的值由A替换为B,在此之前,线程2将变量的值由A替换为C,又由C替换为A,然后线程1执行CAS时发现变量的值仍然为A,所以CAS成功。但实际上这时的现场已经和最初不同了,尽管CAS成功,但可能存在潜藏的问题,例如下面的例子:

现有一个用单向链表实现的堆栈,栈顶为A,这时线程T1已经知道A.next为B,然后希望用CAS将栈顶替换为B:
head.compareAndSet(A,B);
在T1执行上面这条指令之前,线程T2介入,将A、B出栈,再pushD、C、A,此时堆栈结构如下图,而对象B此时处于游离状态:
此时轮到线程T1执行CAS操作,检测发现栈顶仍为A,所以CAS成功,栈顶变为B,但实际上B.next为null,所以此时的情况变为:
其中堆栈中只有B一个元素,C和D组成的链表不再存在于堆栈中,平白无故就把C、D丢掉了。

以上就是由于ABA问题带来的隐患,各种乐观锁的实现中通常都会用版本戳version来对记录或对象标记,避免并发操作带来的问题,在Java中,AtomicStampedReference也实现了这个作用,它通过包装[E,Integer]的元组来对对象标记版本戳stamp,从而避免ABA问题,例如下面的代码分别用AtomicInteger和AtomicStampedReference来对初始值为100的原子整型变量进行更新,AtomicInteger会成功执行CAS操作,而加上版本戳的AtomicStampedReference对于ABA问题会执行CAS失败:

    private static AtomicInteger at = new AtomicInteger(100);private static AtomicStampedReference asr = new AtomicStampedReference(100, 0);public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {try {TimeUnit.SECONDS.sleep(1);at.compareAndSet(100, 101);at.compareAndSet(101, 100);} catch (InterruptedException e) {e.printStackTrace();}});t1.start();Thread t2 = new Thread(() -> {try {TimeUnit.SECONDS.sleep(2);boolean b = at.compareAndSet(100, 101);System.out.println("AtomicInteger " + b);//AtomicInteger true} catch (InterruptedException e) {e.printStackTrace();}});t2.start();Thread t3 = new Thread(() -> {try {TimeUnit.SECONDS.sleep(1);asr.compareAndSet(100, 101, asr.getStamp(), asr.getStamp() + 1);asr.compareAndSet(101, 100, asr.getStamp(), asr.getStamp() + 1);} catch (InterruptedException e) {e.printStackTrace();}});t3.start();Thread t4 = new Thread(() -> {try {int stamp = asr.getStamp();System.out.println("stamp = " + stamp);TimeUnit.SECONDS.sleep(2);boolean b = asr.compareAndSet(100, 101, stamp, stamp + 1);System.out.println("AtomicStampedReference " + b);//AtomicStampedReference false} catch (InterruptedException e) {e.printStackTrace();}});t4.start();}

stamp = 0
AtomicInteger true
AtomicStampedReference false

AtomicStampedReference相关推荐

  1. aba问题mysql_解决CAS机制中ABA问题的AtomicStampedReference详解

    AtomicStampedReference是一个带有时间戳的对象引用,能很好的解决CAS机制中的ABA问题,这篇文章将通过案例对其介绍分析. 一.ABA问题 ABA问题是CAS机制中出现的一个问题, ...

  2. java 线程aba,JAVA中CAS-ABA的问题解决方案AtomicStampedReference

    了解CAS(Compare-And-Swap) CAS即对比交换,它在保证数据原子性的前提下尽可能的减少了锁的使用,很多编程语言或者系统实现上都大量的使用了CAS. JAVA中CAS的实现 JAVA中 ...

  3. java intbyreference_java并发包(1)-AtomicReference和AtomicStampedReference

    AtomicReference原子应用类,可以保证你在修改对象引用时的线程安全性,比较时可以按照偏移量进行 这里的cas操作本身是原子的,但是在某些场景下会出现异常场景 线程判断被修改对象是否可以正确 ...

  4. AtomicStampedReference实现

    AtomicStampedReference解决ABA问题 AtomicStampedReference与AtomicReference差异参考: 无锁的对象引用:AtomicReference 带有 ...

  5. AtomicStampedReference源码分析

    之前的文章已经介绍过CAS的操作原理,它虽然能够保证数据的原子性,但还是会有一个ABA的问题.     那么什么是ABA的问题呢?假设有一个共享变量"num",有个线程A在第一次进 ...

  6. AtomicStampedReference解决CAS的ABA问题

    AtomicStampReference 解决CAS的ABA问题 什么是ABA ABA问题:指CAS操作的时候,线程将某个变量值由A修改为B,但是又改回了A,其他线程发现A并未改变,于是CAS将进行值 ...

  7. atomicReference 的使用和AtomicStampedReference 解决ABA的问题

    atomicReference 的使用和AtomicStampedReference 解决ABA的问题 参考文章: (1)atomicReference 的使用和AtomicStampedRefere ...

  8. 并发编程 — AtomicStampedReference 详解

    AtomicInteger.AtomicBoolean.AtomicLong.AtomicReference 这些原子类型,它们无一例外都采用了基于 volatile 关键字 +CAS 算法无锁的操作 ...

  9. 详解AtomicReference,AtomicStampedReference与AtomicMarkableReference的区别

    前言 我们知道CAS是最轻量级的,性能比锁更高,单CPU的开销很大,CAS是英文单词Compare and Swap的缩写,翻译过来就是比较并替换. CAS原子类操作包括如AtomicBoolean, ...

最新文章

  1. Java 对象的生命周期
  2. boxFilter 滤波器实现
  3. pandas将dataframe中的年、月、日数据列合并成完整日期字符串、并使用to_datetime将字符串格式转化为日期格式
  4. 用CMD命令实现一个简单的网页搜索
  5. EL表达式隐含对象和jstl命名冲突,jstl无法取的值
  6. 华为2019暑期实习笔试题
  7. yum安装本地rpm包_在 Fedora 中安装替代版本的 RPM 包
  8. vant状态页组件van-empty - 使用篇
  9. 《恋上数据结构第1季》动态扩容数组原理及实现
  10. 注意!腾讯语音助手也已抵达战场(内部不止这一个)
  11. 【注意】关于fgets函数
  12. 《JavaScript 高级程序设计(第四版)》—— 06 集合引用类型
  13. SGG Trans【Bridging Knowledge Graphsto Generate Scene Graphs】
  14. 新特汽车在重庆“复活”:打造新品牌“电动屋”,已获网约车牌照
  15. ios wifi 定位_iOS开发Wifi 定位原理及iOS Wifi 列表获取
  16. 逍遥棋牌怎么样,是不是骗人的?
  17. 把简单的 Postman,玩出花样?
  18. 黑苹果入门:必备工具篇
  19. Java RESTful Web Service实战(第2版)
  20. 公募基金主要业务逻辑

热门文章

  1. JavaScript学习(六十五)—数组知识点总结
  2. 二手车没有车险能过户吗?
  3. 为什么有些工厂,3000块一个月不包吃住还能招到工人?
  4. 未来的创业者和公司,一定要具备三大能力
  5. 好的营销,往往叫广深高速
  6. 线下社群要如何拉新呢?
  7. 【以太坊源码阅读】椭圆曲线加密和EIP155
  8. C语言手写快排算法,两个值时也可以使用哦!
  9. IP数据报格式,IP分片,IP编址,子网掩码
  10. Qt4_子类化QMainWindow