多線程下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

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