自旋鎖、偏向鎖、輕量級鎖與重量級鎖


java 中synchronized 鎖的優化都是依賴對象頭實現的,網上有關於對象頭的資料大致概況如下圖:

對象頭信息是實現synchronized 優化的基礎;

主要思想就是通過代碼層面的判斷,來減少真正鎖的獲取與釋放時,CPU 用戶態/內核態的切換帶來的高成本(根本原因是java中的每個線程都映射到內核中一個線程,阻塞與喚醒都需要工作空間的切換);

  自旋鎖與偏向鎖都適用於實際應用中,可能只有單個線程在使用鎖的情況;

  輕量級鎖適用於同步塊占用時間很短的多線程競爭場景;

  自旋鎖、偏向鎖、輕量級鎖都是通過自旋的方式來獲取鎖;

自旋鎖:

  獲取鎖時,增加獲取次數的設置;

  自適應的自旋鎖(1.6)會根據之前自旋的情況來判斷下次自旋的次數;如果之前自旋成功概率較高,那么就增加下一次的自旋次數,否則減少自旋次數;

偏向鎖:

  大概意思就是如果某個線程獲取鎖成功,下次就更偏向於該線程獲得鎖;

  條件:

    鎖對象的對象頭-鎖標志位為01

  線程A在獲取鎖時,

    1、查看鎖對象的對象頭線程ID是否為當前線程A,如果是,則獲取鎖成功;

    2、否則CAS自旋替換線程ID,如果替換成功則獲取成功;

    3、更新失敗則升級鎖類型為輕量級鎖;

輕量級鎖:

  在線程棧幀中創建一個Lock record,用於保存鎖對象的對象頭信息;鎖對象頭中保存一個當前持有輕量級鎖的線程的棧幀Lock record的指針;

  條件:

    鎖對象的對象頭-鎖標志位為00

  線程A在獲取鎖時,

    1、比較線程A的棧幀中Lock record 與 鎖對象頭的棧幀指針是否一致;如果一致則獲取成功;

    2、否則CAS自旋更改鎖對象頭的棧幀指針為當前線程A的棧幀Lock record地址,如果替換成功則獲取輕量級鎖成功;

    3、更新失敗則升級為重量級鎖;

重量級鎖:

  重量級鎖依賴於操作系統的Mutex Lock,需要操作系統對線程狀態的切換;目前JVM的線程切換需要操作系統切換用戶態到核心態,成本較高,所以叫重量級鎖;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM