CAS的三大问题和解决方案

一、ABA问题的解决方案

变量第一次读取的值是1,后来其他线程改成了3,然后又被其他线程修改成了1,原来期望的值是第一个1才会设置新值,第二个1跟期望不符合,但是,可以设置新值。

解决方案:

(a)增加一个自定义的版本号变量,记录修改日志,每次修改一次,就加1 。当值相同时,还要比较版本号,如果版本号也一样,才能更新成新的值。
(b)采用原子引用类 AtomicStampedReference,通过控制变量值的版本号,来确保CAS的正确性,比较两个值引用是否一致,只有一致才会更新成新值。

二、无限循环问题(自旋)的解决方案

底层使用一个while循环来实现的,所以Atomic类设置值进入一个无限循环,只要失败了就不停的循环,再次疯狂的尝试。高并发场景下,多个线程频繁修改同一个值,则会导致大量线程执行compareAndSet的方法时,要循环 n 次才能更新成功,就是大量线程执行一个重复的空循环(自旋锁),造成系统的大量开销。

解决方案:

(a)采用 jdk 8 中的 LongAdder,分段CAS + 自动分段迁移。

三、多原子的变量问题的解决方案

一般的Atomic类,只能保证一个共享变量的原子性。

解决方案:

(a)采用 java 并发包的 AtomicReference,这个是封装自定义对象的,多个变量可放一个自定义对象中,然后它会检查该对象的引用是否是相同。如果多个线程,同时对一个对象变量的引用进行修改,AtomicReference 的 CAS 算法可解决并发冲突问题。

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值