CAS(乐观锁)与ABA问题
cas是什么
CAS 全稱 compare and swap 或者compare and exchange 比較并且交換。用于在沒有鎖的情況下,多個線程對同一個值的更新。
cas原理
例如,我們對一個int i進行遞增操作。原來,為了線程安全,需要在遞增代碼上加一把鎖 sync 。CAS的實現方式為:不去加鎖,讀取當前的值,將原值存入E中,然后計算,得到計算結果1,這個時候的新值存入V中。然后調用一個比較并交換的方法(底層匯編指令) 這個方法的作用是:如果E和現在的i值相等,說明沒有地方對原值進行過操作。那么就將i的值替換為V的值。
如果有別的線程對i進行操作了(例如:i被修改為了2),那么將i的新值讀取,然后再進行一次計算操作(將i=2 作為最初值,進行計算,得到結果3 )。然后再次調用比較并交換的方法,去進行值的更新操作。一直循環,直到更新成功(有的鎖在更新到一定次數后,會進行鎖升級,但是這個跟CAS沒關系)
CAS底層原理
cas追代碼的時候,可以追到native部分,但是,這里面提供的都是一些接口,但是沒有具體的底層實現。具體的實現,需要看虛擬機的實現。
jvm的底層實現分為不同的公司的不同實現:Oracle的為hotSpot實現,這個是最常見的。我們可以看到代碼的開源版本是openjdk。比如阿里的taobaoVM 。Ibm 的J9等。
在openjdk 中,unsafe類在實現CompareAndSwapInt 方法時,是調用的Atomic類的cmpxchg方法,然后一通方法調用,最終調用到匯編語言的 lock_if_mp(lock if multi processors 如果是多個cpu 那么會鎖定) cmpxchg 這兩個 指令 ,最終執行 lock cmpxchg 指令
這里的lock是一一個鎖定北橋芯片的鎖,用于解決當前cpu在進行比較和修改的時候的其他cpu對該值進行操作的問題。保證線程安全。
aba問題
在線程A進來時,讀取到的值為1。在A進行計算的時候線程B取到了i的值,然后更新為了2。然后線程C又取到i=2的值,進行C的計算后,然后得到結果為1 又將i的值修改為了1 這個時候,線程A進行判斷的時候,會認為在其計算過程中沒有其他線程對i進行過操作。ABA有的會產生影響,有的不會,如果沒有影響,不需要考慮該問題。
aba問題解決
解決方法:加上版本號,每個線程讀取完,賦值的時候,修改版本號,比較的時候,對比i值+版本號。
總結
以上是生活随笔為你收集整理的CAS(乐观锁)与ABA问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: windows蓝屏代码
- 下一篇: 【python 6】Numpy