1 synchronized 關鍵字的作用
- 互斥訪問:
當一個執行緒獲得了由 synchronized 修飾的方法或程式碼塊的鎖後,其他執行緒必須等待該鎖被釋放才能繼續執行。
這種機制保證了同一時間只有一個執行緒可以執行被 synchronized 修飾的程式碼段。 - 可見性:
synchronized 關鍵字確保了當一個執行緒修改了共享變數後,這些修改對其他執行緒是可見的。
當一個執行緒釋放鎖時,它會強制重新整理執行緒的工作記憶體到主記憶體,其他執行緒在獲取鎖時會從主記憶體中讀取最新的變數值。 - 有序性:
synchronized 關鍵字保證了在 synchronized 程式碼塊中的操作按照它們出現的順序執行,防止了指令重排序。
2 synchronized 的使用
2.1 修飾方法
public synchronized void method() {
// ...
}
- 當一個方法被 synchronized 修飾時,它會在該方法的入口處獲取鎖,在方法結束或丟擲異常時釋放鎖。
- 鎖的物件是當前物件的例項(如果是例項方法)或類物件(如果是靜態方法)。
2.2 修飾程式碼塊
public void method() {
synchronized (lockObject) {
// ...
}
}
- 當一個程式碼塊被 synchronized 修飾時,它會獲取指定物件的鎖。
- 鎖的物件可以是任何物件,通常使用一個私有靜態的鎖物件來確保執行緒安全。
3 底層實現原理
synchronized 關鍵字的底層實現涉及到 Java 物件的監視器鎖(Monitor)。每個 Java 物件都可以成為一個監視器鎖,當一個執行緒獲取了某個物件的鎖後,其他執行緒必須等待該鎖被釋放才能繼續執行。監視器鎖的資訊儲存在 Java 物件頭中。