当前位置: 首页 > news >正文

CAS带来的ABA问题以及解决方案

CAS带来的ABA问题

在这里插入图片描述
线程1和线程2同时对变量i = 1 进行操作,线程1对i进行了两次操作,先将i+1 写出,后又进行了i-1并写出,线程2过来读的时候与原来值1仍然是相等的,虽然值仍然相等,但是i的值却发生过改变,期间从1变成2又变成1(ABA问题)。

解决方案

对值的每次操作都进行记录,需要保证是一个原子操作。
在这里插入图片描述
java中使用AtomicMarkableReference或者AtomicStampedReference。
AtomicMarkableReference:使用boolean表示是否修改过。
AtomicStampedReference: 使用int 记录改变的次数(推荐)!

AtomicStampedReference 使用:

class Stu {private String name;private Integer age;
getter/setter
}//参数1: 对象 
//参数2:初始版本号AtomicStampedReference<Stu> accountBalance = new AtomicStampedReference<>(stu, 0);源码:
public AtomicStampedReference(V var1, int var2) {this.pair = AtomicStampedReference.Pair.of(var1, var2);
}
static <T> Pair<T> of(T var0, int var1) {return new Pair(var0, var1);  //底层使用Pair对象。
}private Pair(T var1, int var2) {this.reference = var1;  //真实对象this.stamp = var2;   //版本号
}
Thread threadA = new Thread(() -> {int[] stampHolder = new int[1];//获取对象Stu stu1 = accountBalance.get(stampHolder);//改变的次数int currentStamp = stampHolder[0];System.out.println("Thread A: 当前年龄 = " + stu1.getAge() + ", 当前版本号= " + currentStamp);stu1.setAge(100000);boolean success = accountBalance.compareAndSet(stu1, stu1, currentStamp, currentStamp + 1);/***源码:* 参数1:  期望值* 参数2:  新值* 参数3: 原有修改次数* 参数4: 新修改次数(一般使用原有修改次数+1)*    public boolean compareAndSet(V var1, V var2, int var3, int var4) {**         //原始对象值  包含对象和修改的次数*         Pair var5 = this.pair;*         return*              var1 == var5.reference  //对象不是同一个(期望值不一样)  就不再进行操作*              && var3 == var5.stamp   // 版本号不一样  就不再进行操作*              && (var2 == var5.reference && var4 == var5.stamp   //操作对象与原来一样并且操作次数也一样 表示中间的值没有被其他线程修改过,无需继续修改*                      ||*                  this.casPair(var5, AtomicStampedReference.Pair.of(var2, var4)));  //进行CAS操作*     }******/if (success) {System.out.println("Thread A: 更新成功,新的年龄 = " + accountBalance.getReference().getAge() + ",新的版本号" + accountBalance.getStamp());} else {System.out.println("Thread A: 更新失败");}});

http://www.mrgr.cn/news/19505.html

相关文章:

  • CSS英文换行
  • 启动.cmd文件一闪而过,看不到报错信息
  • 第二证券:什么是券商理财,券商理财有风险吗?
  • 【C++】OOP面向对象思想
  • uniapp树洞烦恼分享系统 微信小程序设计与实现 80igt
  • 前端请求的路径baseURL怎么来的 ?nodejs解决cors问题的一种方法
  • GIT使用时最常见的问题解决方法
  • 策略变更管理:确保MySQL数据恢复策略的持续适应性
  • Java数据结构
  • 咖啡机配网数据
  • 非标机械设计项目“规范”笔记
  • Elasticsearch数据写入过程
  • Sui Hacker House曼谷站报名开启:在Devcon 2024期间探索Sui区块链创新
  • HTTPS SEO优势
  • 1. GIS开发工程师岗位职责、技术要求和常见面试题
  • 利用机器学习和SHAP分析学生成绩影响因素
  • QQ聊天记录删除了怎么恢复?学会这3个方法,简单又有效
  • 基于飞桨paddle2.6.1+cuda11.7+paddleRS开发版的目标提取-道路数据集训练和预测代码
  • UML 图
  • wordpress发送邮件的方法?怎么配置功能?