CAS的ABA问题详解及解决办法

CAS的ABA问题详解

  • ABA问题
  • 在多线程场景下CAS会出现ABA问题,关于ABA问题这里简单科普下,例如有2个线程同时对同一个值(初始值为A)进行CAS操作,这三个线程如下
    • 1.线程1,期望值为A,欲更新的值为B
    • 2.线程2,期望值为A,欲更新的值为B
  • 线程1抢先获得CPU时间片,而线程2因为其他原因阻塞了,线程1取值与期望的A值比较,发现相等然后将值更新为B,然后这个时候出现了线程3,期望值为B,欲更新的值为A,线程3取值与期望的值B比较,发现相等则将值更新为A,此时线程2从阻塞中恢复,并且获得了CPU时间片,这时候线程2取值与期望的值A比较,发现相等则将值更新为B,虽然线程2也完成了操作,但是线程2并不知道值已经经过了A->B->A的变化过程。
  • ABA问题带来的危害:
  • 小明在提款机,提取了50元,因为提款机问题,有两个线程,同时把余额从100变为50
  • 线程1(提款机):获取当前值100,期望更新为50,
  • 线程2(提款机):获取当前值100,期望更新为50,
  • 线程1成功执行,线程2某种原因block了,这时,某人给小明汇款50
  • 线程3(默认):获取当前值50,期望更新为100,
  • 这时候线程3成功执行,余额变为100,
  • 线程2从Block中恢复,获取到的也是100,compare之后,继续更新余额为50!!!
  • 此时可以看到,实际余额应该为100(100-50+50),但是实际上变为了50(100-50+50-50)这就是ABA问题带来的成功提交。

 

二、解决办法

ABA问题的优化(AtomicStampedReference)

  • ABA问题导致的原因,是CAS过程中只简单进行了“值”的校验,再有些情况下,“值”相同不会引入错误的业务逻辑(例如库存),有些情况下,“值”虽然相同,却已经不是原来的数据了。
  • 优化方向:CAS不能只比对“值”,还必须确保的是原来的数据,才能修改成功。
  • 解决方法: 在变量前面加上版本号,每次变量更新的时候变量的版本号都+1,即A->B->A就变成了1A->2B->3A。
  • 常见实践:“版本号”的比对,一个数据一个版本,版本变化,即使值相同,也不应该修改成功。
  • CAS的应用场景:
    • 应用于简单的数据计算
    • 适合线程冲突少的场景
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章