Java并发编程之CAS算法

CAS介绍


CAS(Compare And Swap)比较并交换,CAS算法的过程是这样的:它包含了3个参数CAS(V,E,N)。

V 表示要更新的变量
E 表示旧的预期值
N 表示新值。

当V的值等于E 的值的时候,表示当前变量V 没有被其他线程更新,那么将V 的值设置为N
当V的值不等于E 值的时候,表示当前变量V 被其他线程更新,那么就不会对V 进行更新。

CAS例子


假设有两个线程想要更新变量 V=10;
线程A 想把V 更新为20;
线程B 想把V 更新为30;
对于线程A 来说,V 值为10,旧的预期值E当然也为10,希望更新的值N 为20;
如果B 线程在A 线程更新之前完成对V 的更新,那么此时V 的值为30 。
那么对于A 线程来说 V 的值等于30 ,而预期值E 还是10,这说明V 的值已经被更新了,A线程就什么也不做。

CAS的缺点


  • CPU开销大,当多个线程同时尝试修改某一变量时,线程将尝试不断自旋,直至修改成功,这将给CPU带来压力。
  • 只能保证单个变量的原子性操作,对于多个变量进行的原子性更新,CAS无能为力。
  • ABA问题

ABA问题


由于CAS以上的机制,如果上面的例子中,不但有B 线程对V 进行修改,还有其他线程也对V 成功进行了修改,那么就有可能修改后的结果V 还是等于10,那么,此时A 线程进行V 和E 的比较,结果相等,将认为V 未被修改,这样就会出现线程安全问题。
简单来说,当一个值从A变成B,又更新回A,普通CAS机制会误判通过检测。

版本号方式解决ABA问题


每次在执行数据的修改操作时,都会带上一个版本号,一旦版本号和数据的版本号一致就可以执行修改操作并对版本号执行+1 操作,否则就执行失败。因为每次操作的版本号都会随之增加,所以不会出现 ABA 问题,因为版本号只会增加不会减少。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值