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的應用場景:
    • 應用於簡單的數據計算
    • 適合線程衝突少的場景
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章