1、ABA问题示例

package com.example.sgg.juc;import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;/*** ABA问题* Created by 奔跑的蜗牛 on 2022/5/5 0005.* 每天学习一点点,每天进步一点点*/
public class ABADemo {// 主内存共享变量,初始值为1,版本号为1private static AtomicInteger atomicInteger = new AtomicInteger(1);public static void main(String[] args) {// t1,期望将1改为10new Thread(() -> {// 第一次拿到的时间戳int value = atomicInteger.get();System.out.println(Thread.currentThread().getName() + " 第1次拿到值为:" + value);// 休眠5s,确保t2执行完ABA操作try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}// t2将时间戳改为了3,cas失败boolean b = atomicInteger.compareAndSet(value, 10);System.out.println(Thread.currentThread().getName() + " CAS是否成功:" + b);System.out.println(Thread.currentThread().getName() + " 当前最新值为:" + atomicInteger.get());}, "t1").start();// t2进行ABA操作new Thread(() -> {// 第一次拿到的时间戳int value = atomicInteger.get();System.out.println(Thread.currentThread().getName() + " 第1次拿到值为:" + value);// 休眠,修改前确保t1也拿到同样的副本,初始值为1try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}// 将副本改为20,再写入,紧接着又改为1,写入,每次提升一个时间戳,中间t1没介入atomicInteger.compareAndSet(value, 20);System.out.println(Thread.currentThread().getName() + " 第2次拿到值为:" + atomicInteger.get());atomicInteger.compareAndSet(20, value);System.out.println(Thread.currentThread().getName() + " 第3次拿到值为:" + atomicInteger.get());}, "t2").start();}
}

2、ABA问题解决示例

package com.example.sgg.juc;import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicStampedReference;/*** 解决ABA问题* Created by 奔跑的蜗牛 on 2022/5/5 0005.* 每天学习一点点,每天进步一点点*/
public class ABASolveDemo {// 主内存共享变量,初始值为1,版本号为1private static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(1, 1);public static void main(String[] args) {// t1,期望将1改为10new Thread(() -> {// 第一次拿到的时间戳int stamp = atomicStampedReference.getStamp();System.out.println(Thread.currentThread().getName() + " 第1次时间戳:" + stamp + " 值为:" + atomicStampedReference.getReference());// 休眠5s,确保t2执行完ABA操作try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}// t2将时间戳改为了3,cas失败boolean b = atomicStampedReference.compareAndSet(1, 10, stamp, stamp + 1);System.out.println(Thread.currentThread().getName() + " CAS是否成功:" + b);System.out.println(Thread.currentThread().getName() + " 当前最新时间戳:" + atomicStampedReference.getStamp() + " 最新值为:" + atomicStampedReference.getReference());}, "t1").start();// t2进行ABA操作new Thread(() -> {// 第一次拿到的时间戳int stamp = atomicStampedReference.getStamp();System.out.println(Thread.currentThread().getName() + " 第1次时间戳:" + stamp + " 值为:" + atomicStampedReference.getReference());// 休眠,修改前确保t1也拿到同样的副本,初始值为1try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}// 将副本改为20,再写入,紧接着又改为1,写入,每次提升一个时间戳,中间t1没介入atomicStampedReference.compareAndSet(1, 20, stamp, stamp + 1);System.out.println(Thread.currentThread().getName() + " 第2次时间戳:" + atomicStampedReference.getStamp() + " 值为:" + atomicStampedReference.getReference());atomicStampedReference.compareAndSet(20, 1, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1);System.out.println(Thread.currentThread().getName() + " 第3次时间戳:" + atomicStampedReference.getStamp() + " 值为:" + atomicStampedReference.getReference());}, "t2").start();}
}

简单理解就是AtomicStampedReference使用了单向版本号,不可逆转,每次修改则版本号递增,以此来解决ABA的问题

3、ABA问题带来的危害

个人理解:

1、一条线程造成的ABA问题对业务的数据不会造成影响,因为最终一致,可以看做这个ABA为回滚动作;

举例说明:

一个线程同时做了,购票(票数减一)和退票操作(票数加一),就算是发生了ABA,而另一个购票线程依然还是根据旧的票数减一操作,最终结果不受影响(此处为举例,实际购票退票理论上不是一个线程做的)

2、对于两条以上线程造成的ABA问题对业务数据会造成影响,因为影响的最终一致性;

举例说明:

小牛取款,由于机器不太好使,多点了几次取款操作。后台threadA和threadB工作,
此时threadA操作成功(100->50),threadB阻塞。正好牛妈打款50元给小牛(50->100),
threadC执行成功,之后threadB运行了,又改为(100->50), 钱变少了,因为原本多点击的threadB是无法执行的,因此牛妈打款后,最终金额应该是100。

CAS的ABA问题及解决代码示例相关推荐

  1. 18.AtomicReference、AtomicStampReference底层原理。多个变量更新怎么保证原子性?CAS的ABA问题怎么解决?

    老王:小陈啊,上一章我们说了AtomicInteger.AtomicBoolean的底层原理,这一篇我们就来说说Atomic系列的另一个分类AtomicReference和AtomicStampRef ...

  2. CAS中ABA问题的解决

    什么是CAS? Compare and Swap (比较交换),使用CAS来保证线程的对变量的原子操作,避免被其他线程所干扰. CAS原理:其中包含三个参数 要修改的变量 变量的预期值 要更性的参数 ...

  3. cas引出的ABA问题?如何解决?- 理解原子引用、时间戳(版本号)原子引用

    ABA问题: 假如有两个线程1,2: cas下:1.线程取值完等待,2线程取值并把A改成B,有把B改成A,这是1线程执行会任务A还是原来的A没有发生改变,如果不在乎中间结果,只看收尾,那么没必要解决A ...

  4. CAS详解及ABA问题的解决

    序言 由于最近项目上遇到了高并发问题,而自己对高并发,多线程这里的知识点相对薄弱,尤其是基础,所以想系统的学习一下,以后可能会出一系列的JUC文章及总结 ,同时也为企业级的高并发项目做好准备. 本文是 ...

  5. JUC04-- CAS自旋 、CAS自旋锁、ABA问题及解决办法、18大原子类

    文章目录 JUC04 课程任务概览 CAS CAS原理简介 CAS发展: CAS是什么? CAS原理: CAS优点: **CAS底层实现-引出Unsafe类** ==CAS自旋实现个人总结== Ato ...

  6. elementUI解决el-checkbox自定义样式、@change样式的失效 等bug - 代码示例

    elementUI解决el-checkbox样式(自定义样式问题) 1. 需求(如图所示): 2. 代码示例说明:(截图示下) 测试正常. /* 热门职位 + 区域 组件替换样式 */ .hot-jo ...

  7. AtomicStampedReference解决CAS的ABA问题

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

  8. elementui表格宽度适应内容_解决elementui表格操作列自适应列宽代码示例

    本篇文章小编给大家分享一下解决elementui表格操作列自适应列宽代码示例,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看. 写死宽度时是这样的: 开始 ...

  9. mysql解决aba问题_AtomicStampedReference解决CAS的ABA问题

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

最新文章

  1. 传递字符串_一道经典面试题:字符串在Java中如何通过“引用”传递
  2. Python的深copy和浅copy
  3. python基础语法手册_说一说python中的几个基础语法
  4. js返回上一页并刷新
  5. MySQL这三道常见的面试题,你有被问过吗?
  6. 事理图谱:一种纯学术需求、无法落地、漏洞百出的新技术或新概念?
  7. .两个windowsform之间的值传递
  8. python 上传文件
  9. 魔兽国服修改服务器地址,魔兽国服退役服务器上架暴雪官方商店
  10. “繁盛计划”,纾困中国餐饮难题背后的美团式解法
  11. 用 FragmentTabHost 实现底部菜单
  12. 用HTML5的canvas实现抽奖刮刮卡的效果(只需十几行代码)
  13. My 2007 Fash game: Elite Shooter
  14. Mac系统升级后导致AS不能使用SVN
  15. 蹦的一下,又来一个新属性scrollbar-gutter
  16. 编写Java程序,实现简单的五子棋博弈游戏(美和易思Java练习习题)
  17. 生成分布式项目批次号
  18. linux开发环境工具
  19. Drupal网站系统的应用
  20. 前端模块化——彻底搞懂AMD、CMD、ESM和CommonJS

热门文章

  1. 如何进行实时频谱分析仪的二次开发——MATLAB、C++、labview开发环境的部署
  2. “2009福布斯中国名人榜”榜单
  3. [附源码]java毕业设计企业职工福利发放管理系统
  4. idea2019本地导入lombok不兼容问题
  5. java一键配置环境变量_Java环境变量一键配置工具|
  6. 如何管理保护布线系统,从四个方面来说明
  7. 双目是个词吗_什么双目的四字词语
  8. 移动端浏览器预览word、excel、ppt
  9. 尽人事,听天命,十二轮面试最终圆梦字节,记一次最难面试记录
  10. Ubuntu 22.04正式发布, 更像苹果了