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 更新失敗。