synchonized加鎖的虛擬機實現

synchonized實現有兩種方式,一種是直接加在方法上,對整個方法進行加鎖。另一種是對方法內的某一個代碼塊進行加鎖,那麼這兩種加鎖方式在虛擬機內的實現是怎樣的呢。

對方法直接進行加鎖:方法級的同步時隱式的,即無須通過字節碼指令來控制,它實現在方法調用和返回操作之間。虛擬機可以從方法常量池的方法表結構中的ACC_SYNCHRONIZED訪問標誌得知一個方法是否聲明爲同步方法。當方法調用時,調用指令將會檢查方法的ACC_SYNCHRONIZED訪問標誌是否被設置,如果設置了,執行線程就要先成功持有管程,然後才能執行方法,最後當方法完成時釋放管程(無論是否正常完成都會釋放)。在方法執行期間,執行線程持有了管程,其他任何線程都無法再獲取到同一個管程。如果一個同步方法執行期間拋出了異常,並且在方法內部無法處理此異常,那麼這個方法所持有的管程將在異常拋到同步方法之外時自動釋放。

對方法內部的某一個代碼塊進行加鎖:java虛擬機的指令集中有monitorenter和monitorexit兩條指令來支持synchronized關鍵字的語義,正確實現synchronized關鍵字需要javac 編譯器和java虛擬機兩者共同協作支持。在同步代碼塊執行開始的時候,將會調用monitorenter指令,當代碼塊結束時將調用monitorexit指令,編譯器必須確保無論方法通過何種方式完成,方法中調用過的每條monitorenter指令都必須執行其對應的monitorexit指令,而無論這個方法是正常結束還是異常結束。爲了保證在方法異常完成時monitorenter和monitorexit指令依然可以正確配對執行,編譯器會自動產生一個異常處理器,這個異常處理器聲明可處理所有異常,它的目的就是用來執行monitorexit指令。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章