輕量級鎖

鎖優化的過程:無鎖->偏向鎖->輕量級鎖->重量級鎖

假設許多存在數據競爭的情形都是一個線程執行完同步代碼后,另外一個線程才開始競爭鎖;

問題1 如何獲取輕量級鎖?
沒有引入偏向鎖的情形
當線程T1請求對象鎖,即JVM執行monitorenter字節碼指令時,

如果最初對象鎖處于無鎖狀態unlocked,即共享對象頭mark wordtag bits值為01,偏向模式標記位是0
首先,在線程T1的私有棧中分配lock record
此時,lock record由兩部分組成:displaced hdrowner

然后復制共享對象頭此時的mark record值到lock recorddisplaced hdr,使得owner指針指向共享對象的內存地址;

接著,嘗試使用CAS設置共享對象頭mark word指向線程T1的lock record
此時必操作成功,因為此時只有線程T1在請求鎖,則設置共享對象頭mark wordtag bits值為00,線程T1獲得輕量級鎖,開始執行同步代碼;

當T1執行完同步代碼,執行monitorexit釋放鎖時,嘗試使用CAS操作設置共享對象頭mark word指向線程T1的lock record

如果成功,則說明并沒有其他線程來競爭對象鎖,對象鎖仍處于輕量級狀態lightweight locked

如果失敗,則說明在線程T1還持有輕量級鎖時,有其他線程在競爭對象鎖,然后才去一種比較慢的合理方式釋放T1持有的輕量級鎖,同時通知處于等待的線程去競爭獲取鎖。

如果共享對象處于輕量級鎖狀態lightweight locked,即共享對象頭mark wordtag bits值為00,即有線程T1已經獲得輕量級鎖,在執行同步代碼,現在線程T2也開始請求對象鎖了,則線程T2嘗試使用CAS競爭設置共享對象頭mark word指向線程T2的lock record
如果失敗,則表明線程T1還持有鎖,還在臨界區域內,就將輕量級鎖膨脹為重量級鎖;
如果成功,則表示線程T1已經釋放鎖了,退出臨界區域了,否則可能出現兩個線程同時進入臨界區域,不滿足鎖的排他性;線程T2開始執行同步代碼;

問題2:輕量級鎖是如何處理鎖重入情形的?
首先,判斷對象鎖是否處于輕量級狀態;如果是,則接著判斷對象頭mark word 記錄的lock record 是否指向當前線程的;如果是,則在前述lock record中壓入一個0值。這樣是為了方便重入輕量級鎖的釋放,因為當釋放輕量級鎖時,如果對象頭mark word指向的地址記錄一個0值,就可以知道是重入輕量級鎖釋放鎖了,直接釋放,不需要更新對象頭mark word。這里也是sun公司的hotspot提供的不同于其他虛擬機的輕量級鎖優化。

問題3:輕量級鎖如何升級為重量級鎖?

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容