深入Java synchronized:底層機(jī)制與鎖升級(jí)
synchronized是Java中用于線程同步的重要關(guān)鍵字,其底層實(shí)現(xiàn)和鎖升級(jí)機(jī)制對(duì)并發(fā)性能至關(guān)重要。本文將深入探討synchronized的運(yùn)作細(xì)節(jié),并結(jié)合示例代碼分析鎖的升級(jí)過程。
以下示例代碼演示了不同鎖狀態(tài)的轉(zhuǎn)換:
public static void main(String[] args) throws InterruptedException { // Hotspot虛擬機(jī)啟動(dòng)后存在4秒延遲才啟用偏向鎖 Thread.sleep(5000); 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()); } }, "線程A").start(); Thread.sleep(1000); new Thread(() -> { synchronized (obj) { System.out.println(Thread.currentThread().getName() + "獲取鎖執(zhí)行中。。。n" + ClassLayout.parseInstance(obj).toPrintable()); } }, "線程B").start(); // 睡眠5秒后 Thread.sleep(5000); System.out.println(Thread.currentThread().getName() + ClassLayout.parseInstance(obj).toPrintable()); }
運(yùn)行此代碼,觀察輸出結(jié)果,即可看到鎖狀態(tài)從無鎖到偏向鎖、輕量級(jí)鎖,甚至重量級(jí)鎖的轉(zhuǎn)換過程(注意:高版本jvm已棄用偏向鎖)。
synchronized的鎖升級(jí)過程如下:
立即學(xué)習(xí)“Java免費(fèi)學(xué)習(xí)筆記(深入)”;
- 無鎖狀態(tài): 對(duì)象初始狀態(tài),對(duì)象頭包含哈希碼、GC年齡等信息。
- 偏向鎖 (已在較新JVM版本中棄用): 只有一個(gè)線程訪問同步塊時(shí),JVM將鎖偏向該線程,對(duì)象頭記錄偏向線程ID,減少鎖獲取開銷。
- 輕量級(jí)鎖: 當(dāng)?shù)诙€(gè)線程嘗試獲取鎖時(shí),如果偏向鎖的線程不在同步塊中執(zhí)行,偏向鎖升級(jí)為輕量級(jí)鎖。輕量級(jí)鎖通過自旋嘗試獲取鎖,自旋次數(shù)有限,失敗則升級(jí)為重量級(jí)鎖。
- 重量級(jí)鎖: 線程掛起,操作系統(tǒng)調(diào)度,開銷較大,適用于高競(jìng)爭(zhēng)場(chǎng)景。
示例代碼的輸出結(jié)果將展示鎖狀態(tài)的轉(zhuǎn)換,例如從無鎖到輕量級(jí)鎖,再到可能出現(xiàn)的重量級(jí)鎖。 (由于偏向鎖被棄用,可能不會(huì)顯示偏向鎖狀態(tài))。 分析這些輸出結(jié)果,可以更深入地理解鎖升級(jí)的動(dòng)態(tài)過程。
總之,理解synchronized的底層機(jī)制和鎖升級(jí)過程,對(duì)掌握J(rèn)ava并發(fā)編程和性能優(yōu)化至關(guān)重要。 通過代碼實(shí)踐和結(jié)果分析,可以更有效地學(xué)習(xí)和應(yīng)用這些知識(shí)。
? 版權(quán)聲明
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載。
THE END