多執行緒系列學習 ABA問題

2021-10-22 22:50:36 字數 2055 閱讀 6261

aba問題,描述的是乙個變數v,它的值經歷a -> b ->a的變化,導致看起來好像沒有變一樣,其實,第二次出現的a已經不是第一次出現的a了,是被修改過的。

下面復現aba問題,並解決

測試**:

public class abatest  catch (interruptedexception e) 

// 執行緒a看到的那個0,已經是被執行緒b修改過的0了(num目前的狀態0 - 1 - 0)

num.compareandset(0,2);

// stampedreference.compareandset("a", "c",1,2);

latch.countdown();

}).start();

new thread(() -> ).start();

try catch (interruptedexception e)

system.out.println("最終 num = "+num.get());

// stampedreference的值,沒有修改為c

// system.out.println("最終 stampedreference = "+stampedreference.getreference()+",stampedreference.getstamp()="+stampedreference.getstamp());

}

測試結果:

num 初始值為 0,執行緒a準備設定 num 為 2

num 初始值為 0,執行緒b 設定 num 為 1

num 初始值為 1,執行緒b 設定 num 為 0

最終 num = 2

結果說明:num是atomicinteger 型別的變數,保證其原子操作,但是並不能防止aba情況的出現:執行緒a第二次看到的0是被執行緒b修改回來的0,並不是第一次遇到的0。

stampedreference 初始值為 a,執行緒a準備將其設定為c

stampedreference 初始值為 a,執行緒b準備將其設定為b

stampedreference 初始值為 b,執行緒b準備將其設定為a

最終 stampedreference = a,stampedreference.getstamp()=3

可以看到,stampedreference 最終的值是a,也就是執行緒b第二次修改後的值,因為它的版本號為3,不是1。atomicstampedreference解決aba問題,在於它提供了乙個版本號,在進行cas操作時,不僅比較引用是否相等,還比較版本號和預期的是否一樣,兩者都一樣才會進行更新,請看原始碼:

/**

* atomically sets the value of both the reference and stamp

* to the given update values if the

* current reference is to the expected reference

* and the current stamp is equal to the expected stamp.

** @param expectedreference the expected value of the reference

* @param newreference the new value for the reference

* @param expectedstamp the expected value of the stamp

* @param newstamp the new value for the stamp

* @return if successful

*/public boolean compareandset(v expectedreference,

v newreference,

int expectedstamp,

int newstamp)

其中,stamp 可以看作是版本號,而pair物件只是對reference 和 stamp的包裝。

多執行緒原子性 CAS以及ABA問題

通常情況下為了保證安全,在乙個執行緒對乙個數值訪問時要上鎖,但是為了保證效率,cas中是不上鎖的。列如 現在有乙個值為0,讀取這個值,並且將其存在e中,則 e 0。然後對e進行遞增運算,有計算結果設為v。e 後,設乙個新的值為n 即 n e 這時去檢視e,如果e還是為0,則表明沒有其他的執行緒修改e...

多執行緒程式設計系列學習之 lock關鍵字

概念 lock 語句獲取給定物件的互斥 lock,執行語句塊,然後釋放 lock。持有 lock 時,持有 lock 的執行緒可以再次獲取並釋放 lock。阻止任何其他執行緒獲取 lock 並等待釋放 lock。lock 只適用單機情況,分布式和負債均衡可以考慮分布式鎖。形式lock this lo...

SpringCloud系列學習

在講解springcloud 之前,我們先講一講單體架構系統。所謂的單體架構就是所有功能,都放在乙個應用裡。比如後面要講的乙個單體產品服務應用,提供資料和檢視都在乙個springboot裡。單體架構系統有其好處,如便於開發,測試,部署也很方便,直接打成乙個 jar 或者 war,就什麼都好了。不過單...