Java多线程之通俗易懂讲解CAS

一、什么是CAS机制

CAS即CompareAndSet被称之为无锁优化,从设计思想来说CAS属于乐观锁,主要应对高并发下多个线程操作同一个变量的线程安全问题

二、CAS原理
int count = 0;
compareAndSet(count, 1, 2)

此代码块需要对count执行加1操作此处的count就相当于下图中的valueOffset,1就相当expect,2就相当于update,如果expect等于valueOffset才会将count设为2也就是图中的update,如果不相等则重新预估expect的值直到成功为止,这个不断预估expect值的过程称之为自旋,是在内存中进行的。
在这里插入图片描述
为什么要进行count是否等于expect的比较呢?我们可以想象一种 高并发的场景,有多个线程需要同时对count进行加1操作如果线程1一开始获取到了count的值为1,此时的expect值为1,update为2,当线程1还没执行完对count的加1操作时CPU分配给线程1的时间片到了,这个时候线程2进来了执行了对count的一个自增操作count变为了2,当再次轮到线程1操作时如果不进行valueOffset是否等于expect的操作就会导致count重新变回1,这样就出现了线程不安全的问题。

三、CAS机制代码演示

在这里插入图片描述

三、ABA问题以及解决方案
  • 线程1获取到如下的值,CPU使用时间片到了,进入到了等待状态
    在这里插入图片描述
  • 这时线程2获得CPU资源将值修改为10
    在这里插入图片描述
  • 接着又将值修改回到3
    在这里插入图片描述
  • 接着线程1又获取到了CPU资源,这是对于线程1来说valueOffset相当于没有变,这就是ABA问题
    在这里插入图片描述
  • 如果valueOffset为整数ABA问题是没有影响的但是当我们把valueOffset引申为对象,这就不一定了因为对象在这个变来变去的过程中可能改变了其中属性的值,如何解决ABA问题,添加一个版本号version就能有效的解决,每进行一次操作时就对version进行加1操作,每次操作前同时进行version的校验
四、CAS机制的缺点
  • CPU开销较大
    在并发量比较高的情况下,如果许多线程反复尝试更新某一个变量,却又一直更新不成功,循环往复,会给CPU带来很大的压力。
  • 不能保证代码块的原子性
    CAS机制所保证的只是一个变量的原子性操作,而不能保证整个代码块的原子性。比如需要保证3个变量共同进行原子性的更新,就不得不使用Synchronized了。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值