Java多線程編程中,synchronized的鎖升級機制是如何工作的?

Java多線程編程中,synchronized的鎖升級機制是如何工作的?

深入探討synchronized鎖升級機制

Java中的synchronized關(guān)鍵字是實現(xiàn)線程同步的關(guān)鍵,其底層依賴HotSpot虛擬機的鎖升級機制來優(yōu)化性能。本文將結(jié)合示例代碼分析synchronized的鎖升級過程及原理。

示例代碼及分析

以下代碼演示了synchronized的使用,并利用ClassLayout工具觀察鎖狀態(tài)變化(需要添加jdk.internal.misc.Unsafe依賴):

public static void main(String[] args) throws InterruptedException {     Object obj = new Object();     System.out.println("初始狀態(tài) =====================" + "n" + ClassLayout.parseInstance(obj).toPrintable());     new Thread(() -> {         synchronized (obj) {             System.out.println(Thread.currentThread().getName() + "獲取鎖執(zhí)行中。。。n"                     + ClassLayout.parseInstance(obj).toPrintable());         }     }, "thread-a").start();      Thread.sleep(1000);      new Thread(() -> {         synchronized (obj) {             System.out.println(Thread.currentThread().getName() + "獲取鎖執(zhí)行中。。。n"                     + ClassLayout.parseInstance(obj).toPrintable());         }     }, "thread-b").start();      Thread.sleep(5000);     System.out.println(Thread.currentThread().getName() + ClassLayout.parseInstance(obj).toPrintable()); }

鎖升級流程

synchronized的鎖升級機制旨在平衡性能和線程安全,主要包含以下狀態(tài):

  1. 無鎖狀態(tài): 對象初始狀態(tài),沒有線程持有鎖
  2. 輕量級鎖: 當(dāng)一個線程訪問同步塊時,jvm會在該線程的幀中創(chuàng)建鎖記錄,并嘗試將對象頭中的Mark word復(fù)制到鎖記錄中。如果成功,則該線程獲得輕量級鎖。
  3. 重量級鎖: 如果多個線程競爭同一個鎖,輕量級鎖升級為重量級鎖。重量級鎖依賴操作系統(tǒng)互斥量,開銷較大。

運行結(jié)果解讀

高版本JVM已取消偏向鎖,鎖升級流程通常為無鎖-輕量級鎖-重量級鎖。運行結(jié)果會顯示對象頭Mark Word狀態(tài)的改變,反映鎖的升級過程。 具體狀態(tài)值會因JVM版本和運行環(huán)境而異,但總體趨勢是鎖狀態(tài)從初始狀態(tài)逐步轉(zhuǎn)變?yōu)檩p量級鎖,甚至重量級鎖,最后回到無鎖狀態(tài)。

立即學(xué)習(xí)Java免費學(xué)習(xí)筆記(深入)”;

總結(jié)

synchronized的鎖升級機制是HotSpot JVM的優(yōu)化策略,通過不同的鎖狀態(tài)來適應(yīng)不同的并發(fā)場景,在單線程訪問時效率最高,多線程競爭時則會升級為重量級鎖以保證線程安全。理解鎖升級機制有助于編寫更高效的多線程程序。 需要注意的是,ClassLayout工具的使用需要一定的JVM內(nèi)部知識,其輸出結(jié)果也需要根據(jù)具體情況進(jìn)行分析。

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點贊5 分享