CAS的缺点

1、循环时间长,开销大

cas方法底层有一个do....while....循环。

以Unsafe的getAndAddInt为例

 public final int getAndAddInt(Object var1, long var2, int var4) {
        int var5;
        do {
            var5 = this.getIntVolatile(var1, var2);
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

        return var5;
    }

如果compareAndSwapInt()方法失败,就会一直尝试。如果CAS长时间一直不成功,可能会给CPU带来很大开销。

2、只能保证一个共享变量的原子操作

对于多个共享变量的原子操作,就不能用cas来保证其原子性,只能用加锁来保证。

3、ABA问题

CAS算法实现的一个重要前提需要提取内存中某时刻的数据并在当下时刻比较并交换,那么在这个时间差类会导致数据的变化。

在cas保证原子性的过程中,其实是有猫腻的。

线程A与线程B并发访问共享变量 int s = 0;

设想线程A的操作比较复杂,耗时很大,线程B则只比较后修改s,在一次线程A处理的时间内,线程B可以完成多次处理。

  1. 比如同一时间线程A与B在主物理内存中拷贝到自己的工作内存中的值都是0。
  2. 然后线程B将s 改为1,(这时主物理内存中的s还没有被A改变),然后线程B通过CAS比较并交换后,成功将内存中的s改为1。
  3. 注意:然后线程B在A修改之前又通过CAS将主内存中的s从1又改为0.
  4. 这时线程A在工作内存中将s改为999,Cas写入主内存中的时候发现s还是0(这个0是改过之后的0),与期望值一样,修改成功。

这样ABA问题可能不会给操作结果造成影响,但是可能会给具体的业务场景造成影响。(并不能代表这个过程是没问题的)

ABA问题的解决

原子引用与ABA问题的解决

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值