1. 程式人生 > 實用技巧 >偏向鎖,輕量級鎖,重量級鎖的加鎖過程

偏向鎖,輕量級鎖,重量級鎖的加鎖過程

Java SE1.6 為了改善效能, 使得 JVM 會根據競爭情況, 使用如下 3 種不同的鎖機制

  • 偏向鎖(Biased Lock )
  • 輕量級鎖( Lightweight Lock)
  • 重量級鎖(Heavyweight Lock)

上述這三種機制的切換是根據競爭激烈程度進行的, 在幾乎無競爭的條件下, 會使用偏向鎖, 在輕度競爭的條件下, 會由偏向鎖升級為輕量級鎖, 在重度競爭的情況下, 會升級到重量級鎖。

1.偏向鎖

注意 JVM 提供了關閉偏向鎖的機制, JVM 啟動命令指定如下引數即可-XX:-UseBiasedLocking


根據偏斜鎖機制是否開啟, 物件 MarkWord 狀態以不同方式轉換的過程
無鎖 -> 偏向鎖

偏向鎖的獲取方式是將物件頭的 MarkWord 部分中, 標記上執行緒ID, 以表示哪一個執行緒獲得了偏向鎖。

1.如果為可偏向狀態, 則嘗試用 CAS 操作, 將自己的執行緒 ID 寫入MarkWord

  • 如果 CAS 操作成功(狀態轉變為下圖), 則認為已經獲取到該物件的偏向鎖, 執行同步塊程式碼 。
  • 補充: 一個執行緒在執行完同步程式碼塊以後, 並不會嘗試將 MarkWord 中的 thread ID 賦回原值 。這樣做的好處是: 如果該執行緒需要再次對這個物件加鎖,而這個物件之前一直沒有被其他執行緒嘗試獲取過鎖,依舊停留在可偏向的狀態下, 即可在不修改物件頭的情況下, 直接認為偏向成功。

如果 CAS 操作失敗, 則說明, 有另外一個執行緒 Thread B 搶先獲取了偏向鎖。 這種狀態說明該物件的競爭比較激烈, 此時需要撤銷 Thread B 獲得的偏向鎖,將 Thread B 持有的鎖升級為輕量級鎖。 該操作需要等待全域性安全點 JVM safepoint ( 此時間點, 沒有執行緒在執行位元組碼)。

2.如果是已偏向狀態, 則檢測 MarkWord 中儲存的 thread ID 是否等於當前 thread ID 。

  • 如果相等, 則證明本執行緒已經獲取到偏向鎖, 可以直接繼續執行同步程式碼塊
  • 如果不等, 則證明該物件目前偏向於其他執行緒, 需要撤銷偏向鎖