关于CAS和CAS中的ABA问题

CAS:

CAS是Compare and swap的首字母缩写,意思为比较并且交换。CAS的功能也正如翻译的一样的比较并交换,我们的线程进行工作的时候会把主内存的值读入工作内存,在进行操作,我们以++操作进行解释。

首先我们的线程先把主内存中的值读到各自的工作内存中。

然后两个线程都对number进行了++操作。

这时候第一个线程更快一点,想要把工作内存中修改的值写回到主内存中。旧的预期值就是上一次冲内存中读到工作内存中的值,会把这个旧的预期值和主内存进行比较,也就是Compare的过程,如果主内存中的值和预期值相同就代表,主内存没有被其他线程修改,可以放心写回,这时候主内存的number就会变为1。这就是swap过程。

 之后第二个线程也想写回主内存,但是这个线程旧的预期值和主内存的值进行比较后,发现并不相同,这时候第二个线程无法进行写回,然后第二个线程会再次把主内存的值读取到自己的工作内存中进行操作。

这时候第二个线程2如果比较迅速,想要写回,比较预期值和主内存相同,这时候就会进行写回操作。

CAS是一个原子性操作,但是CAS是基于硬件的支持,才有了软件的原子性。Java中的原子类就是基于CAS设计的。

CAS的ABA问题:

什么是ABA问题,就是我们把数据A修改成数据B再把B改回A,这时候你不知道你的数据是修改过的还是没有修改的。这会有出现什么问题呢?我们可以设想以下场景。我们去银行手动去银行取钱,这时候ATM机器有点故障,我点了一下取钱却发生了两次,这时候,有两个线程开始工作。

 

这时候线程1执行取钱操作,然后对比旧的预期值和资金是否相等,发现相等,就进行修改操作,此时资金就变成了50,然后线程2也想进行取款操作,但是发现旧的预期值和资金不相等,则没有完成取款操作。

乍一看没有什么问题但是,突然这时候有人给你转账50,然后资金变成了100,然后线程2发现主内存和旧的预期值相同,则会进行修改操作。这时候我们发现ATM多修改了一次数据,我们白白的少了50元。这就是问题的关键,由于我们的ABA问题导致,我们的共享变量被多修改了一次。我们要如何解决ABA问题。也非常的简单,我们引入版本号就可以解决这样的问题。我们给主内存设置一个version,当线程把主内存加载到工作内存的时候,也同时会加载version这个版本号,然后我们线程每进行写回之后,版本号就会+1,这时候其他线程会比较主内存和工作内存的值和版本号,只有值和版本号相同才能进行写回操作,否则将会重新将主内存的值和版本号读取工作内存,再进行下一次操作。

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值