1. 程式人生 > >Java之多執行緒安全(屌絲版,兩大解決思路,要麼不去競爭(開闢執行緒副本)、要麼有順序的競爭資源(用鎖規定執行緒秩序))

Java之多執行緒安全(屌絲版,兩大解決思路,要麼不去競爭(開闢執行緒副本)、要麼有順序的競爭資源(用鎖規定執行緒秩序))

0、多執行緒安全,如果多個執行緒操作一個變數,每次都能達到預期的結果,那麼說明當前這個類起碼是執行緒安全的,我這白話的,可能有點噁心。

 

1、看看牛人是怎麼說的,為什麼多執行緒併發是不安全的?

在作業系統中,執行緒是不再擁有資源的,程序是擁有資源的。而執行緒是由程序建立的,一個程序可以建立多個執行緒,這些執行緒共享著程序中的資源。所以,當執行緒一起併發執行時,同時對一個數據進行修改,就有可能造成資料不一致,因為A和B執行緒拿到資料時的狀態是不一樣的

這個例子比較好

int number = 0;

該欄位number

有兩個執行緒共享它,並同時去修改它,每個執行緒去給它+1

你的預期是number == 2

但是真實結果可能是1

原因:
a、第一個執行緒計算時拿到number是0,然後給它+1,計算時結果是1
b、第二個執行緒計算時拿到的number也是0,而不是1,因為是並行的,記憶體中的number還是0,也進行一次計算後,number還是 == 1

c、理想預期是第二個執行緒拿到第一個執行緒計算後的結果,即拿到的就是1,再去計算一下,結果 number == 2

當第一個執行緒將結果寫回到記憶體中的 number 後,第二個執行緒也將結果寫回到記憶體中的number中去,這就會把第一個執行緒的計算結果給覆蓋了,所以最終的結果還是1

 

2、怎麼解決上面的併發問題?

思路1:給共享的資料,加把鎖,每次哪個執行緒拿到鎖,才能操作

思路2:讓執行緒也擁有資料,不去共享程序中的資料

 

3、思路1

使用鎖機制、synchronized

使用Lock

使用java.util.concurrent下的執行緒安全的集合類

 

4、思路2

使用ThreadLocal,把共享的資源,線上程物件中,再開闢一份獨立的,成為執行緒私有變數,這樣的話,別的執行緒就算修改類共享的變數,你自己的資源一點也不受影響,既滿足了你需要的資源,又不會引起併發問題,完美的解決方案啊,大神牛逼