compare and swap ABA 问题和解决方案
CAS ABA 问题图解
如上图所示三个线程 T1,T2,T3 更新内存中的值 V。具体执行时刻沿着时间线。
-
T1
,T2
同时读取到内存中的值V
,保存到线程私有变量 A
此时A
的值为100
。 -
T1
线程的A = 100
(也就是当前线程私有保存的 V 的一份拷贝),计算B = A - 50
, 此时比较A 和 V
相等,将V
的值更新为50
。 -
T2
被阻塞。 -
T3
读取到V = 50
,保存在A
中。计算B = A + 50 = 100
,比较A 和 V
的值,相等。将V
的值更新为100
。注意此时内存中的V
的值经历了从100->50->100
的过程,这就是所谓的 ABA 问题
。 -
T2
接着执行,计算B = A - 50 = 50
。比较A 和 V
的值,相等。将V
的值更新为50
。
解决方案
本质原因:内存中 V 的值经过了改变,又变回了原值。但是没有记录这个信息。
怎么办?
加一个版本号来记录 V 的版本。这就是代价,要表示这个变化过程的代价。
解决 ABA 问题图解
CAS 更新成功条件
- V = A
- 版本相同
- 可以看到
T1 和 T2
读取到的 version 都是01
。 -
T1
执行完成后,更新内存中V
的值为50
,版本号为02
。 -
T3
执行完成后,更新内存中V
的值为100
,版本号为03
。 -
T2
读取到的 version 是01
,but 此时内存中的 version 是03
,版本不匹配 T2 更新失败。