多執行緒-synchronized鎖
阿新 • • 發佈:2022-03-15
java物件頭結構
Mark Word 資料結構
synchronized 鎖升級流程
偏向鎖-->輕量級鎖-->重量級鎖
樣例程式碼:
public void test() {
synchronized (object) {
// 省略
}
}
偏向鎖過程
當Thread-A 進入 synchronize 程式碼塊時 ,先將 執行緒id 存入 object物件頭中,(如果object呼叫過hashCode方法,那麼Mark Word 中由於存放了hashCode 沒有剩餘的空間存放執行緒id會直接使用輕量級鎖)表示該鎖為Thread-A 專用,如果Thread-B也進入了 synchronize 程式碼塊時,發現object物件頭中已經存入了Thread-A的id,存在資源競爭關係則進行鎖膨脹,使用輕量級鎖
偏向鎖結構圖
當物件呼叫了hashCode方法後,Mark Word 中沒有空間儲存執行緒id ,偏向鎖會失效
物件的偏向鎖可以手動關閉
輕量級鎖加鎖過程
每一個執行緒執行有都有一個私有棧,當鎖升級至輕量級鎖時升建立一個鎖記錄,鎖記錄裡有鎖記錄地址和指向object物件的指標。
升級至輕量級鎖後,會嘗試使用CAS操作將Mark Word 中的與鎖記錄地址進行交換來進行獲取鎖。假如Thread-A獲取到鎖,此時Thread-B進入同步程式碼塊,會使用CAS操作進行獲取鎖 ,如果CAS操作失敗後會根據作業系統來決定是否進行自旋,自旋過程中CAS操作成功了則結束。失敗則進行鎖膨脹,升級至重量級鎖。
升級至重量級鎖後會為object物件申請一個monitor物件(一個物件只能有一個monitor),將物件頭中的鎖記錄更改為monitor地址,Monitor 中owner設定為當前鎖的擁有者,當前執行緒進入EntryList 阻塞,等待擁有鎖的執行緒釋放鎖後將其喚醒
monitor(重量級鎖) 結構