深入探討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):
- 無鎖狀態(tài): 對象初始狀態(tài),沒有線程持有鎖。
- 輕量級鎖: 當(dāng)一個線程訪問同步塊時,jvm會在該線程的棧幀中創(chuàng)建鎖記錄,并嘗試將對象頭中的Mark word復(fù)制到鎖記錄中。如果成功,則該線程獲得輕量級鎖。
- 重量級鎖: 如果多個線程競爭同一個鎖,輕量級鎖升級為重量級鎖。重量級鎖依賴操作系統(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)聲明
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載。
THE END