多线程下CAS的ABA问题有什么危害

什么是CAS

CAS 是一个原子操作,包含了三个操作数–内存位置,预期原值和新值。如果内存位置的值和预期原值匹配,那么处理器自动将该位置的值更新为新值,否则不做任何操作

JUC下面的包都是基于 CAS 的

多线程情况下 CAS 存在的问题

ABA问题

线程A准备用CAS将变量有1 替换成 2,但是在这之前,线程B将变量的值由1 替换成3,又替换成了1,这时候线程A执行CAS会成功,一般场景下ABA并不会出现什么问题,但是当涉及到引用的时候就会出问题。

场景是用链表来实现一个栈,初始化向栈中压入B、A两个元素,栈顶head指向A元素。

在某个时刻,线程1试图将栈顶换成B,但它获取栈顶的oldValue(为A)后,被线程2中断了。线程2依次将A、B弹出,然后压入C、D、A。然后换线程1继续运行,线程1执行compareAndSet发现head指向的元素确实与oldValue一致,都是A,所以就将head指向B了。但是线程2在弹出B的时候,将B的next置为null了,因此在线程1将head指向B后,栈中只剩了一个孤零零的元素B。但按预期来说,栈中应该放的是B → A → D → C

解决ABA 问题
  1. 互斥同步锁synchronized
  2. J.U.C 包提供了一个带有时间戳的原子引用类 AtomicStampedReference 来解决该问题,它通过控制变量的版本来保证 CAS 的正确性。

参考:
https://www.cnblogs.com/yingying7/p/12573240.html
https://hesey.wang/2011/09/resolve-aba-by-atomicstampedreference.html
https://www.cnblogs.com/barrywxx/p/8487444.html
https://www.jianshu.com/p/7339c3701a0f

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章