1. 程式人生 > >java 中如何避免多執行緒不安全

java 中如何避免多執行緒不安全

1.建立不可變物件

2. 執行緒封閉:把一個可變物件封裝到一個執行緒內部,或者使用ThreadLocal

3.使用volatile變數

volatile變數記憶體語義
1. 當對一個volatile變數進行寫操作的時候,JMM會把該執行緒對應的本地記憶體中的共享變數的值重新整理到主記憶體中。
2. 當一個執行緒讀volatile變數時,JMM會把該執行緒對應的本地記憶體變數置為無效,要求執行緒從主記憶體中讀該變數。

總結:volatile對任意單個volatile變數的讀寫具有原子性,但是對於複合操作不具有原子性。

4 .使用final變數

記憶體語義:

  1. 在建構函式內對一個final域的寫入,與隨後把這個被構造物件
    的引用賦值給一個引用變數,這兩個操作之間不能進行重排序。
  2. 初次讀入一個包含final物件的引用,與隨後初次讀這個final域,這兩個操作之間不能重排序。

5.使用鎖(synchronized,可重入鎖)

鎖的記憶體語義:

  1. 當執行緒釋放鎖時,JMM會把該執行緒對應的本地記憶體中的共享變數重新整理到主記憶體中。
  2. 當執行緒獲取鎖時,JMM會把當前執行緒擁有的本地記憶體共享變數置為無效,執行緒從主記憶體中讀取共享變數。

注:可重入鎖指的是在一個執行緒中可以多次獲取同一把鎖。可重入鎖的最大作用是避免內部死鎖。在很多情況下執行緒需要多次進入鎖內執行任務。在很多情況下執行緒需要多次進入鎖內執行任務。
+ 遞迴呼叫
+ 此執行緒呼叫同一物件其他synchronized或者同步鎖函式。