解讀synchronized鎖的釋放機制
synchronized鎖的釋放機制
synchronized 鎖的釋放機制是通過 JVM 底層的 Monitor 鎖模型和 計數器機制 實現(xiàn)的。
以下是具體的釋放邏輯和觸發(fā)條件:
一、鎖釋放的觸發(fā)條件
正常執(zhí)行結束
當線程執(zhí)行完 synchronized
修飾的代碼塊或方法時,JVM 會自動調用 monitorexit
指令釋放鎖。
- 同步代碼塊:通過
monitorenter
和monitorexit
指令顯式控制鎖的獲取與釋放。 - 同步方法:通過
ACC_SYNCHRONIZED
標志隱式觸發(fā)鎖的獲取和釋放,方法結束時自動釋放鎖。
異常退出
- 如果在
synchronized
代碼塊或方法中拋出未捕獲的異常,JVM 會執(zhí)行monitorexit
指令釋放鎖。 - 編譯時會為同步代碼塊生成兩個
monitorexit
指令:一個用于正常退出,另一個用于異常路徑。
顯式調用 wait()
- 線程在
synchronized
代碼塊內調用wait()
方法時 - 會暫時釋放鎖并進入等待狀態(tài),直到其他線程調用
notify()
/notifyAll()
喚醒它
二、鎖釋放的核心機制
計數器遞減
- 每個對象關聯(lián)一個 Monitor 鎖,內部維護一個計數器(
_count
)。 - 線程每次進入
synchronized
代碼塊時計數器加 1,退出時減 1。 - 當計數器歸零時,鎖完全釋放,其他線程可競爭獲取。
Monitor 對象的狀態(tài)管理
- 持有鎖的線程(
_owner
):釋放鎖后,_owner
置為null
,計數器歸零。 - 等待隊列(
_EntryList
和_WaitSet
):鎖釋放后,JVM 會從_EntryList
或_WaitSet
中喚醒線程重新競爭鎖。
三、不同場景的鎖釋放示例
1. 同步代碼塊
public void method() { synchronized (this) { // 代碼邏輯 } // 此處自動執(zhí)行 monitorexit 釋放鎖 }
無論正常結束還是拋出異常,monitorexit
都會觸發(fā)鎖釋放。
2. 同步方法
public synchronized void method() { // 代碼邏輯 } // 方法結束自動釋放鎖
通過 ACC_SYNCHRONIZED
標志隱式管理鎖,無需顯式字節(jié)碼指令。
3. 異常場景
public void method() { synchronized (this) { throw new RuntimeException(); // 觸發(fā)異常,自動釋放鎖 } }
即使未捕獲異常,JVM 也會執(zhí)行 monitorexit
指令釋放鎖。
四、鎖釋放的底層實現(xiàn)(字節(jié)碼層面)
同步代碼塊
編譯后生成 monitorenter
和兩個 monitorexit
(正常退出和異常退出)指令:
public void method(); Code: 0: aload_0 1: dup 2: astore_1 3: monitorenter // 獲取鎖 4: ... // 業(yè)務代碼 13: monitorexit // 正常退出釋放鎖 14: goto 20 17: aload_1 18: monitorexit // 異常退出釋放鎖 19: athrow 20: return
同步方法
方法訪問標志包含 ACC_SYNCHRONIZED
,JVM 在方法入口和出口隱式管理鎖。
五、注意事項
不會釋放鎖的操作
Thread.sleep()
、Thread.yield()
不會釋放鎖。- 線程掛起(如
suspend()
)也不會釋放鎖。
可重入性
- 同一線程可多次獲取鎖(計數器遞增)
- 需對應次數的退出操作才能完全釋放
總結
synchronized 鎖的釋放依賴于 JVM 的 Monitor 模型和計數器機制,通過以下方式觸發(fā):
- 代碼塊或方法正常結束。
- 未捕獲異常拋出。
- 顯式調用
wait()
。 - 其底層通過
monitorexit
指令或隱式標志確保鎖的正確釋放,保障線程安全。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
設置JavaScript自動提示-Eclipse/MyEclipse
自動提示需要2個組件,分別是:ext-4.0.2a.jsb2||spket-1.6.16.jar,需要的朋友可以參考下2016-05-05Java 中的vector和list的區(qū)別和使用實例詳解
在大家還沒有了解vector,list,deque的知識之前,我先給大家介紹下stl,本文重點給大家介紹vector和list的區(qū)別及使用,感興趣的的朋友一起看看吧2017-09-09