最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

synchronized底層原理之JVM層面的鎖實(shí)現(xiàn)細(xì)節(jié)與流程

 更新時(shí)間:2026年01月04日 09:22:53   作者:C雨后彩虹  
本文從JVM底層視角,詳細(xì)拆解了synchronized的實(shí)現(xiàn)邏輯,涵蓋鎖的存儲(chǔ)載體(對(duì)象頭的MarkWord)、鎖的觸發(fā)指令(monitorenter/monitorexit指令和ACC_SYNCHRONIZED標(biāo)志位)以及鎖的調(diào)度機(jī)制,感興趣的朋友跟隨小編一起看看吧

一、前言

在上一篇文章中,我們掌握了其基礎(chǔ)用法、核心特性及適用場(chǎng)景,知道它能解決并發(fā)編程的原子性、可見(jiàn)性、有序性問(wèn)題。但你是否好奇:同樣是加鎖,synchronized為何能實(shí)現(xiàn)“隱式管理”?鎖的狀態(tài)是如何存儲(chǔ)的?線程之間的鎖競(jìng)爭(zhēng)是如何被JVM調(diào)度的?

本文將深入Java虛擬機(jī)(JVM)底層,從“鎖的載體(對(duì)象頭)”“鎖的觸發(fā)指令(字節(jié)碼)”“鎖的核心調(diào)度機(jī)制(monitor)”三個(gè)維度,完整拆解synchronized的實(shí)現(xiàn)邏輯,帶你從“會(huì)用”進(jìn)階到“懂原理”,真正理解隱式鎖的本質(zhì)。

二、對(duì)象頭與Mark Word

Java中所有對(duì)象都可以作為synchronized的鎖對(duì)象,這并非偶然——每個(gè)Java對(duì)象在內(nèi)存中都包含一個(gè)“對(duì)象頭”結(jié)構(gòu),而對(duì)象頭中的“Mark Word”(標(biāo)記字)正是synchronized鎖狀態(tài)的核心存儲(chǔ)載體。簡(jiǎn)單來(lái)說(shuō):synchronized的鎖,本質(zhì)是對(duì)對(duì)象頭Mark Word的狀態(tài)修改與競(jìng)爭(zhēng)

1. Java對(duì)象的內(nèi)存布局

在HotSpot虛擬機(jī)中,Java對(duì)象的內(nèi)存布局分為三部分:

  • 對(duì)象頭(Header) :存儲(chǔ)對(duì)象的核心元數(shù)據(jù),包括鎖狀態(tài)、線程ID、類指針等,是synchronized鎖機(jī)制的核心依賴;
  • 實(shí)例數(shù)據(jù)(Instance Data) :存儲(chǔ)對(duì)象的成員變量(包括從父類繼承的變量),是對(duì)象的核心業(yè)務(wù)數(shù)據(jù);
  • 對(duì)齊填充(Padding) :HotSpot虛擬機(jī)要求對(duì)象內(nèi)存大小必須是8字節(jié)的整數(shù)倍,對(duì)齊填充僅用于補(bǔ)全字節(jié)數(shù),無(wú)實(shí)際業(yè)務(wù)意義。

其中,對(duì)象頭是我們關(guān)注的重點(diǎn),它又分為以下部分:

  • Mark Word :占4字節(jié)(32位虛擬機(jī))或8字節(jié)(64位虛擬機(jī)),存儲(chǔ)鎖狀態(tài)、偏向線程ID、CAS指針、對(duì)象哈希碼、GC分代年齡等信息;
  • Klass Pointer(類指針) :占4字節(jié)(32位虛擬機(jī))或8字節(jié)(64位虛擬機(jī),開(kāi)啟壓縮指針后為4字節(jié)),指向?qū)ο笏鶎兕惖腃lass對(duì)象,用于確定對(duì)象的類型。
  • Array Length(數(shù)組長(zhǎng)度):占4字節(jié)(32位虛擬機(jī))或8字節(jié)(64位虛擬機(jī)),存儲(chǔ)數(shù)組的元素個(gè)數(shù),數(shù)組長(zhǎng)度是只有數(shù)組對(duì)象才有,普通對(duì)象沒(méi)有。

2. Mark Word的結(jié)構(gòu)與鎖狀態(tài)關(guān)聯(lián)

        Mark Word的結(jié)構(gòu)并非固定不變,而是會(huì)根據(jù)對(duì)象的“鎖狀態(tài)”動(dòng)態(tài)變化——JDK1.6為synchronized引入鎖優(yōu)化后,鎖狀態(tài)分為4種:無(wú)鎖狀態(tài)、偏向鎖狀態(tài)、輕量級(jí)鎖狀態(tài)、重量級(jí)鎖狀態(tài)。不同狀態(tài)下,Mark Word存儲(chǔ)的信息不同,目的是在不同并發(fā)場(chǎng)景下平衡性能與安全性。

以64位HotSpot虛擬機(jī)為例,Mark Word的結(jié)構(gòu)如下圖所示:

其中各部分的含義如下:

  • lock:2位的鎖狀態(tài)標(biāo)記位,該標(biāo)記的值不同,整個(gè) Mark Word表示的含義不同。biased_lock 和 lock一起,表達(dá)的鎖狀態(tài)含義如上圖所示;
  • biased_lock:對(duì)象是否啟用偏向鎖標(biāo)記,只占1個(gè)二進(jìn)制位。為1時(shí)表示對(duì)象啟用偏向鎖,為0時(shí)表示對(duì)象沒(méi)有偏向鎖。lock 和 biased_lock共同表示對(duì)象處于什么鎖狀態(tài);
  • age:4位的Java對(duì)象年齡。
  • identity_hashcode:31位的對(duì)象標(biāo)識(shí)hashCode;
  • thread:持有偏向鎖的線程ID;
  • epoch:偏向鎖的時(shí)間戳;
  • ptr_to_lock_record:輕量級(jí)鎖狀態(tài)下,指向棧中鎖記錄的指針;
  • ptr_to_heavyweight_monitor:重量級(jí)鎖狀態(tài)下,指向?qū)ο蟊O(jiān)視器 Monitor的指針;

關(guān)鍵說(shuō)明:

  • 鎖狀態(tài)由“偏向鎖標(biāo)志位”和“鎖標(biāo)志位”共同決定(例如:偏向鎖標(biāo)志位1+鎖標(biāo)志位01=偏向鎖;偏向鎖標(biāo)志位0+鎖標(biāo)志位00=輕量級(jí)鎖);
  • 隨著并發(fā)競(jìng)爭(zhēng)加劇,鎖狀態(tài)會(huì)從“無(wú)鎖→偏向鎖→輕量級(jí)鎖→重量級(jí)鎖”逐步升級(jí),且升級(jí)過(guò)程不可逆(一旦升級(jí)為重量級(jí)鎖,無(wú)法回退為輕量級(jí)鎖或偏向鎖);
  • Mark Word是synchronized鎖機(jī)制的“核心數(shù)據(jù)結(jié)構(gòu)”,所有鎖的獲取與釋放,本質(zhì)都是對(duì)Mark Word中鎖狀態(tài)的修改。

三、鎖的觸發(fā)與釋放

        synchronized是“隱式鎖”,其核心優(yōu)勢(shì)在于無(wú)需手動(dòng)調(diào)用“lock()”“unlock()”方法——這種隱式管理的實(shí)現(xiàn),依賴于JVM在編譯階段為synchronized修飾的代碼插入特定的字節(jié)碼指令。不同用法(修飾方法、修飾代碼塊)對(duì)應(yīng)的字節(jié)碼實(shí)現(xiàn)略有差異,但核心邏輯一致。

1. 修飾代碼塊:monitorenter與monitorexit指令

        當(dāng)synchronized修飾代碼塊時(shí),JVM會(huì)在代碼塊的“進(jìn)入處”插入 monitorenter 指令,在“退出處”(包括正常退出和異常退出)插入 monitorexit 指令。這兩個(gè)指令是鎖獲取與釋放的直接觸發(fā)者。

代碼示例與字節(jié)碼分析:

public class SyncBlockDemo {
    private final Object lock = new Object();
    public void syncBlock() {
        // 同步代碼塊
        synchronized (lock) {
            System.out.println("進(jìn)入同步代碼塊");
        }
    }
}

使用 javap -v SyncBlockDemo.class 命令反編譯,可得到 syncBlock 方法的字節(jié)碼(核心部分):

public void syncBlock();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=3, args_size=1
         0: aload_0
         1: getfield      #2                  // Field lock:Ljava/lang/Object;
         4: dup
         5: monitorenter  // 進(jìn)入同步代碼塊,獲取鎖(核心指令)
         6: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
         9: ldc           #4                  // String 進(jìn)入同步代碼塊
        11: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        14: aload_1
        15: monitorexit   // 正常退出同步代碼塊,釋放鎖(核心指令)
        16: goto          24
        19: astore_2
        20: aload_1
        21: monitorexit   // 異常退出同步代碼塊,釋放鎖(核心指令)
        22: aload_2
        23: athrow
        24: return
      Exception table:
         from    to  target type
             6    16    19   any
}

字節(jié)碼核心邏輯解讀:

  • 0-4行:通過(guò) getfield 指令獲取鎖對(duì)象 lock ,并通過(guò) dup 指令復(fù)制一份鎖對(duì)象引用(用于后續(xù) monitorenter 和 monitorexit 操作);
  • 5行: monitorenter 指令——線程嘗試獲取鎖:若鎖未被持有,則將鎖的持有者設(shè)為當(dāng)前線程,鎖計(jì)數(shù)器+1;若鎖已被當(dāng)前線程持有,則鎖計(jì)數(shù)器+1(可重入性);若鎖被其他線程持有,則當(dāng)前線程阻塞;
  • 6-11行:執(zhí)行同步代碼塊的核心邏輯(打印語(yǔ)句);
  • 15行: monitorexit 指令(正常退出)——釋放鎖,鎖計(jì)數(shù)器-1,當(dāng)計(jì)數(shù)器減為0時(shí),鎖被完全釋放,喚醒等待鎖的線程;
  • 19-23行:異常退出分支——JVM為同步代碼塊自動(dòng)生成異常處理邏輯,確保即使發(fā)生異常,也能通過(guò) monitorexit 釋放鎖,避免鎖泄漏。

關(guān)鍵結(jié)論: monitorenter 和 monitorexit 是synchronized修飾代碼塊的“鎖開(kāi)關(guān)”,JVM通過(guò)這兩個(gè)指令實(shí)現(xiàn)鎖的獲取與釋放,且異常場(chǎng)景的鎖釋放由JVM自動(dòng)保障。

2. 修飾方法:ACC_SYNCHRONIZED標(biāo)志位

        當(dāng)synchronized修飾實(shí)例方法或靜態(tài)方法時(shí),JVM不會(huì)插入 monitorenter 和 monitorexit 指令,而是通過(guò)在方法的“訪問(wèn)標(biāo)志(accessflags)”中添加 ACCSYNCHRONIZED 標(biāo)志位來(lái)實(shí)現(xiàn)鎖機(jī)制。

代碼示例與字節(jié)碼分析:

public class SyncMethodDemo {
    // 同步實(shí)例方法
    public synchronized void syncInstanceMethod() {
        System.out.println("進(jìn)入同步實(shí)例方法");
    }
    // 同步靜態(tài)方法
    public static synchronized void syncStaticMethod() {
        System.out.println("進(jìn)入同步靜態(tài)方法");
    }
}

反編譯后,方法的字節(jié)碼核心部分如下:

// 同步實(shí)例方法
public synchronized void syncInstanceMethod();
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_SYNCHRONIZED  // 新增ACC_SYNCHRONIZED標(biāo)志位
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #3                  // String 進(jìn)入同步實(shí)例方法
         5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
// 同步靜態(tài)方法
public static synchronized void syncStaticMethod();
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED  // 新增ACC_SYNCHRONIZED標(biāo)志位
    Code:
      stack=2, locals=0, args_size=0
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #5                  // String 進(jìn)入同步靜態(tài)方法
         5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return

字節(jié)碼核心邏輯解讀:

  • 同步方法的字節(jié)碼中,沒(méi)有 monitorenter 和 monitorexit 指令,而是通過(guò) ACC_SYNCHRONIZED 標(biāo)志位標(biāo)識(shí)“這是一個(gè)同步方法”;
  • 當(dāng)線程調(diào)用帶有 ACC_SYNCHRONIZED 標(biāo)志的方法時(shí),JVM會(huì)自動(dòng)嘗試獲取鎖:同步實(shí)例方法:鎖對(duì)象為當(dāng)前實(shí)例(this),獲取鎖的邏輯與 monitorenter 一致;同步靜態(tài)方法:鎖對(duì)象為當(dāng)前類的Class對(duì)象,獲取鎖的邏輯與 monitorenter 一致;
  • 方法執(zhí)行完成(正常return或異常拋出)時(shí),JVM會(huì)自動(dòng)釋放鎖,無(wú)需手動(dòng)處理。

關(guān)鍵結(jié)論:synchronized修飾方法的鎖機(jī)制,本質(zhì)是JVM對(duì) ACC_SYNCHRONIZED 標(biāo)志位的解析——將鎖的獲取與釋放邏輯嵌入到方法的調(diào)用與返回流程中,實(shí)現(xiàn)隱式管理。

四、核心鎖調(diào)度機(jī)制

        無(wú)論是 monitorenter 指令,還是 ACC_SYNCHRONIZED 標(biāo)志位,最終都依賴于“monitor”對(duì)象實(shí)現(xiàn)鎖的調(diào)度。monitor是操作系統(tǒng)層面的“互斥量(mutex)”的封裝,是synchronized重量級(jí)鎖的核心載體,負(fù)責(zé)管理線程的鎖競(jìng)爭(zhēng)與等待。

1. monitor的本質(zhì)與結(jié)構(gòu)

monitor的本質(zhì)是一個(gè)“對(duì)象”,在HotSpot虛擬機(jī)中,它由C++語(yǔ)言實(shí)現(xiàn)(對(duì)應(yīng) ObjectMonitor 類)。每個(gè)Java對(duì)象在創(chuàng)建時(shí),都會(huì)關(guān)聯(lián)一個(gè)monitor對(duì)象(可理解為“對(duì)象→monitor”的一對(duì)一映射),當(dāng)線程嘗試獲取鎖時(shí),實(shí)際上是在競(jìng)爭(zhēng)monitor的“所有權(quán)”。

ObjectMonitor 的核心結(jié)構(gòu)如下(簡(jiǎn)化版):

class ObjectMonitor {
    // 持有當(dāng)前monitor的線程(鎖的所有者)
    Thread* owner;
    // 等待鎖的線程隊(duì)列(阻塞狀態(tài))
    Queue* EntryList;
    // 調(diào)用wait()后等待喚醒的線程隊(duì)列
    Queue* WaitSet;
    // 鎖計(jì)數(shù)器(實(shí)現(xiàn)可重入性)
    int count;
    // 遞歸鎖計(jì)數(shù)器(記錄重入次數(shù))
    int recursions;
};

2. 基于monitor的鎖競(jìng)爭(zhēng)流程

        當(dāng)多個(gè)線程競(jìng)爭(zhēng)同一把鎖時(shí),JVM通過(guò)monitor的 owner 、 EntryList 、 WaitSet 三個(gè)核心組件實(shí)現(xiàn)調(diào)度,完整流程如下:

  • 初始狀態(tài) :monitor的 owner 為null, count 為0, EntryList 和 WaitSet 為空;
  • 線程1獲取鎖 :線程1執(zhí)行 monitorenter 指令(或調(diào)用同步方法),發(fā)現(xiàn)monitor的 owner 為null,直接成為 owner , count 置為1,進(jìn)入臨界區(qū)執(zhí)行代碼;
  • 線程2競(jìng)爭(zhēng)鎖 :線程2嘗試獲取鎖時(shí),發(fā)現(xiàn)monitor的 owner 已為線程1,無(wú)法獲取,被JVM放入 EntryList 隊(duì)列,進(jìn)入阻塞狀態(tài)(BLOCKED);
  • 線程1釋放鎖 :線程1執(zhí)行完臨界區(qū)代碼,執(zhí)行 monitorexit 指令(或方法返回), count 減為0,釋放monitor的 owner (置為null),并喚醒 EntryList 中的線程(如線程2);
  • 線程2再次競(jìng)爭(zhēng) :被喚醒的線程2重新嘗試獲取鎖,若此時(shí)monitor的 owner 為null,則成為新的 owner , count 置為1,進(jìn)入臨界區(qū);若仍有其他線程競(jìng)爭(zhēng),則再次進(jìn)入 EntryList 阻塞;
  • 線程調(diào)用wait()方法 :若線程1在持有鎖期間調(diào)用了 wait() 方法,則會(huì)釋放monitor的 owner , count 置為0,自身進(jìn)入 WaitSet 隊(duì)列,進(jìn)入等待狀態(tài)(WAITING);
  • 線程被notify()喚醒 :當(dāng)其他線程調(diào)用同一鎖對(duì)象的 notify() 或 notifyAll() 方法時(shí),JVM會(huì)將 WaitSet 中的線程(如線程1)轉(zhuǎn)移到 EntryList 隊(duì)列,等待再次競(jìng)爭(zhēng)鎖。

3. 重量級(jí)鎖的性能瓶頸根源

        在JDK1.6之前,synchronized直接使用上述monitor機(jī)制(即重量級(jí)鎖),導(dǎo)致性能較差。其核心瓶頸在于:

  • 線程狀態(tài)切換成本高 :線程從 EntryList 的阻塞狀態(tài)(BLOCKED)被喚醒后,需要從“內(nèi)核態(tài)”切換到“用戶態(tài)”,而狀態(tài)切換涉及操作系統(tǒng)內(nèi)核的調(diào)度,耗時(shí)較長(zhǎng);
  • 鎖競(jìng)爭(zhēng)的排他性開(kāi)銷 :即使只有兩個(gè)線程交替競(jìng)爭(zhēng)鎖,也需要頻繁進(jìn)行“阻塞→喚醒”的狀態(tài)切換,無(wú)法充分利用CPU資源。

這也是JDK1.6引入偏向鎖、輕量級(jí)鎖優(yōu)化的核心原因——在低并發(fā)場(chǎng)景下,避免使用重量級(jí)鎖的內(nèi)核態(tài)調(diào)度,提升鎖競(jìng)爭(zhēng)效率。

五、可重入性的底層實(shí)現(xiàn)

        在上一文中我們提到,synchronized具備可重入性——同一線程可以多次獲取同一把鎖,不會(huì)因已持有鎖而阻塞。這一特性的底層實(shí)現(xiàn),依賴于monitor的 count (鎖計(jì)數(shù)器)和 recursions (遞歸鎖計(jì)數(shù)器)。

具體實(shí)現(xiàn)邏輯:

  • 線程第一次獲取鎖時(shí),monitor的 owner 設(shè)為當(dāng)前線程, count 置為1, recursions 置為0;
  • 線程再次獲取同一把鎖時(shí)(如同步方法調(diào)用同步方法),JVM檢測(cè)到當(dāng)前線程已是monitor的 owner ,則直接將 count 加1, recursions 加1(記錄重入次數(shù));
  • 線程每次釋放鎖時(shí), count 減1;
  • 當(dāng) count 減為0時(shí),說(shuō)明線程已完全釋放鎖, owner 置為null,其他線程可競(jìng)爭(zhēng)。

示例驗(yàn)證:

public class ReentrantDemo {
    public synchronized void methodA() {
        System.out.println("進(jìn)入methodA");
        methodB(); // 同一線程調(diào)用同步方法,重入鎖
    }
    public synchronized void methodB() {
        System.out.println("進(jìn)入methodB");
    }
    public static void main(String[] args) {
        new ReentrantDemo().methodA();
    }
}

執(zhí)行流程:

  • 線程調(diào)用 methodA() ,獲取鎖,monitor的 count=1 ;
  • 線程在 methodA() 中調(diào)用 methodB() ,再次獲取同一把鎖,monitor的 count=2 ;
  • methodB() 執(zhí)行完成,釋放鎖, count=1 ;
  • methodA() 執(zhí)行完成,釋放鎖, count=0 ,鎖完全釋放。

關(guān)鍵結(jié)論:可重入性的核心是“鎖計(jì)數(shù)器”——通過(guò)計(jì)數(shù)記錄線程的重入次數(shù),確保線程只有在完全釋放所有重入鎖后,才會(huì)讓出鎖的所有權(quán)。

六、內(nèi)存可見(jiàn)性的底層保障

        在上一文中我們提到,synchronized能保證內(nèi)存可見(jiàn)性——一個(gè)線程對(duì)共享變量的修改,會(huì)被后續(xù)獲取同一把鎖的線程及時(shí)感知。這一特性的底層實(shí)現(xiàn),依賴于JVM在鎖的獲取與釋放過(guò)程中插入的“內(nèi)存屏障”。

1. 內(nèi)存屏障的核心作用

        內(nèi)存屏障是CPU層面的指令,用于禁止指令重排序,并強(qiáng)制刷新工作內(nèi)存與主內(nèi)存的數(shù)據(jù)。JVM通過(guò)插入內(nèi)存屏障,確保:

  • 線程對(duì)共享變量的修改,必須同步到主內(nèi)存;
  • 線程讀取共享變量時(shí),必須從主內(nèi)存加載最新數(shù)據(jù)。

2. synchronized的內(nèi)存屏障插入規(guī)則

JVM為synchronized的鎖獲取與釋放過(guò)程,制定了嚴(yán)格的內(nèi)存屏障插入規(guī)則:

  • 鎖獲取時(shí) :在 monitorenter 指令(或同步方法調(diào)用)后,插入“LoadLoad屏障”和“LoadStore屏障”:
  • LoadLoad屏障:禁止后續(xù)的讀操作與當(dāng)前讀操作重排序;
  • LoadStore屏障:禁止后續(xù)的寫操作與當(dāng)前讀操作重排序;
  • 核心效果:強(qiáng)制線程從主內(nèi)存加載共享變量的最新數(shù)據(jù),避免讀取舊值。
  • 鎖釋放時(shí) :在 monitorexit 指令(或同步方法返回)前,插入“StoreStore屏障”和“StoreLoad屏障”:
  • StoreStore屏障:禁止當(dāng)前寫操作與后續(xù)寫操作重排序;
  • StoreLoad屏障:禁止當(dāng)前寫操作與后續(xù)讀操作重排序,并強(qiáng)制將工作內(nèi)存中的數(shù)據(jù)同步到主內(nèi)存;
  • 核心效果:確保線程對(duì)共享變量的修改已同步到主內(nèi)存,讓其他線程可見(jiàn)。

3. 與volatile的可見(jiàn)性機(jī)制對(duì)比

synchronized與volatile都能保證內(nèi)存可見(jiàn)性,但實(shí)現(xiàn)邏輯不同:

特性

synchronized

volatile

可見(jiàn)性實(shí)現(xiàn)方式

通過(guò)鎖獲取/釋放時(shí)插入的內(nèi)存屏障,間接保證可見(jiàn)性

直接在寫操作后插入StoreLoad屏障,讀操作前插入LoadLoad屏障,直接保證可見(jiàn)性

額外保障

同時(shí)保證原子性、有序性

僅保證可見(jiàn)性、有序性,不保證原子性

適用場(chǎng)景

臨界區(qū)代碼(多操作組合)

單個(gè)共享變量的讀/寫操作

七、總結(jié)

        本文從JVM底層視角,完整拆解了synchronized的實(shí)現(xiàn)邏輯,核心可總結(jié)為“三個(gè)核心載體+一個(gè)調(diào)度機(jī)制”:

  • 鎖的存儲(chǔ)載體 :對(duì)象頭的Mark Word,通過(guò)動(dòng)態(tài)修改鎖狀態(tài)(無(wú)鎖→偏向鎖→輕量級(jí)鎖→重量級(jí)鎖)適配不同并發(fā)場(chǎng)景;
  • 鎖的觸發(fā)指令 :修飾代碼塊時(shí)通過(guò) monitorenter / monitorexit 指令,修飾方法時(shí)通過(guò) ACC_SYNCHRONIZED 標(biāo)志位,實(shí)現(xiàn)隱式鎖管理;
  • 鎖的調(diào)度機(jī)制 :基于monitor對(duì)象( ObjectMonitor )的 owner 、 EntryList 、 WaitSet 組件,實(shí)現(xiàn)線程的鎖競(jìng)爭(zhēng)與等待喚醒;
  • 可見(jiàn)性與可重入性保障 :通過(guò)內(nèi)存屏障保證可見(jiàn)性,通過(guò)monitor的鎖計(jì)數(shù)器實(shí)現(xiàn)可重入性。

        理解這些底層原理,能幫你更深刻地理解synchronized的性能特性——為何JDK1.6要引入鎖優(yōu)化?為何偏向鎖適合單線程場(chǎng)景?為何高并發(fā)下synchronized性能會(huì)下降?這些問(wèn)題,我們將在第3篇“synchronized鎖優(yōu)化深度解析”中詳細(xì)解答。

        下一篇文章,我們將聚焦JDK1.6的鎖優(yōu)化機(jī)制,深入剖析偏向鎖、輕量級(jí)鎖、重量級(jí)鎖的實(shí)現(xiàn)細(xì)節(jié)與升級(jí)流程,帶你理解synchronized性能提升的核心邏輯,敬請(qǐng)關(guān)注!

到此這篇關(guān)于synchronized底層原理之JVM層面的鎖實(shí)現(xiàn)細(xì)節(jié)與流程的文章就介紹到這了,更多相關(guān)synchronized JVM層面內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java解析JSON的六種方案

    Java解析JSON的六種方案

    這篇文章介紹了 6 種 JSON 解析方案,包括 Jackson、Gson、FastJSON、JsonPath、、手動(dòng)解析,分別闡述了它們的功能特點(diǎn)、代碼示例、高級(jí)功能、優(yōu)缺點(diǎn)及適用場(chǎng)景,感興趣的小伙伴跟著小編一起來(lái)看看吧
    2025-01-01
  • 使用SpringBoot請(qǐng)求方式和訪問(wèn)靜態(tài)頁(yè)面

    使用SpringBoot請(qǐng)求方式和訪問(wèn)靜態(tài)頁(yè)面

    SpringBoot支持多種請(qǐng)求方式,包括GET、RESTful、分頁(yè)列表等,常用框架如阿里fastjson、谷歌gson用于JavaBean序列化為Json,性能上Jackson最快,SpringBoot目錄結(jié)構(gòu)包括src/main/java、src/main/resources等
    2025-01-01
  • 深入理解java線程通信

    深入理解java線程通信

    開(kāi)發(fā)中不免會(huì)遇到需要所有子線程執(zhí)行完畢通知主線程處理某些邏輯的場(chǎng)景?;蛘呤蔷€程 A 在執(zhí)行到某個(gè)條件通知線程 B 執(zhí)行某個(gè)操作。下面我們來(lái)一起學(xué)習(xí)如何解決吧
    2019-05-05
  • Java實(shí)現(xiàn)畫圖的詳細(xì)步驟(完整代碼)

    Java實(shí)現(xiàn)畫圖的詳細(xì)步驟(完整代碼)

    今天給大家?guī)?lái)的是關(guān)于Java的相關(guān)知識(shí),文章圍繞著Java實(shí)現(xiàn)畫圖的詳細(xì)步驟展開(kāi),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • JAVA返回PDF文件流并進(jìn)行下載的實(shí)現(xiàn)方法

    JAVA返回PDF文件流并進(jìn)行下載的實(shí)現(xiàn)方法

    這篇文章主要給大家介紹了關(guān)于JAVA返回PDF文件流并進(jìn)行下載的實(shí)現(xiàn)方法,PDF文件流下載是通過(guò)HTTP協(xié)議將服務(wù)器上的PDF文件以流的方式發(fā)送給客戶端,供客戶端保存到本地磁盤或直接在瀏覽器中打開(kāi),需要的朋友可以參考下
    2024-02-02
  • Java單例模式的6種實(shí)現(xiàn)方式詳解

    Java單例模式的6種實(shí)現(xiàn)方式詳解

    這篇文章主要介紹了Java單例模式的6種實(shí)現(xiàn)方式的相關(guān)資料,需要的朋友可以參考下,希望能夠給你帶來(lái)幫助
    2021-09-09
  • Springboot詳解整合SpringSecurity實(shí)現(xiàn)全過(guò)程

    Springboot詳解整合SpringSecurity實(shí)現(xiàn)全過(guò)程

    Spring Security基于Spring開(kāi)發(fā),項(xiàng)目中如果使用Springboot作為基礎(chǔ),配合Spring Security做權(quán)限更加方便,而Shiro需要和Spring進(jìn)行整合開(kāi)發(fā)。因此作為spring全家桶中的Spring Security在java領(lǐng)域很常用
    2022-07-07
  • SpringBoot2種單元測(cè)試方法解析

    SpringBoot2種單元測(cè)試方法解析

    這篇文章主要介紹了SpringBoot2種單元測(cè)試方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • MyBatis學(xué)習(xí)教程之開(kāi)發(fā)Dao的方法教程

    MyBatis學(xué)習(xí)教程之開(kāi)發(fā)Dao的方法教程

    這篇文章主要給大家介紹了關(guān)于MyBatis開(kāi)發(fā)Dao的相關(guān)資料,使用Mybatis開(kāi)發(fā)Dao,通常有兩個(gè)方法,即原始Dao開(kāi)發(fā)方法和Mapper接口開(kāi)發(fā)方法。文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面來(lái)一起看看吧。
    2017-07-07
  • JDK21無(wú)法導(dǎo)入TimeUnit類的解決辦法

    JDK21無(wú)法導(dǎo)入TimeUnit類的解決辦法

    這篇文章主要給大家介紹了關(guān)于JDK21無(wú)法導(dǎo)入TimeUnit類的解決辦法,TimeUnit是java.util.concurrent包下面的一個(gè)類,TimeUnit提供了可讀性更好的線程暫停操作,通常用來(lái)替換Thread.sleep(),需要的朋友可以參考下
    2024-01-01

最新評(píng)論

库尔勒市| 益阳市| 靖江市| 南雄市| 资中县| 渭南市| 英超| 临夏县| 贵南县| 湟中县| 海口市| 尉氏县| 鄂托克旗| 无极县| 大姚县| 鲁山县| 常熟市| 湾仔区| 徐闻县| 嘉善县| 威信县| 天台县| 安西县| 卫辉市| 长武县| 福清市| 兴海县| 怀柔区| 叙永县| 论坛| 定陶县| 西乡县| 云林县| 龙口市| 大余县| 东乡族自治县| 平塘县| 阿拉善右旗| 白河县| 新竹县| 玉树县|