欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java鎖升級機(jī)制超詳細(xì)講解(附實例代碼)

 更新時間:2025年06月14日 14:05:16   作者:java金融  
Java中的synchronized鎖會經(jīng)歷一個從無鎖到偏向鎖,再到輕量級鎖,最后到重量級鎖的升級過程,這種優(yōu)化稱為鎖升級或鎖膨脹,這篇文章主要介紹了Java鎖升級機(jī)制超詳細(xì)講解的相關(guān)資料,需要的朋友可以參考下

引言

最近有個三年左右的兄弟面試java 被問到這樣一道經(jīng)典的八股文面試題: 你講講java里面的鎖升級? 他感覺回答的不是很好,然后回去找資料學(xué)習(xí)了一波,然后下面是他輸出的文章,希望對找工作的其他朋友也有些幫助。

1. 概述

Java 的鎖升級機(jī)制是 JVM 在 JDK 1.6 后引入的重要優(yōu)化策略,目的是在多線程環(huán)境下平衡 線程安全 與 性能開銷。通過動態(tài)調(diào)整鎖的復(fù)雜度,JVM 根據(jù)競爭強(qiáng)度逐步升級鎖的狀態(tài),避免在低競爭場景下使用高成本的重量級鎖。

2. 鎖類型及特點

鎖類型適用場景性能開銷核心機(jī)制
無鎖(Unlocked)無線程競爭極低直接通過 CAS 操作嘗試獲取鎖。
偏向鎖(Biased Locking)單線程重復(fù)訪問(無競爭)極低對象頭記錄偏向線程 ID,后續(xù)同一線程無需競爭,直接獲取鎖。
輕量級鎖(Lightweight Lock)低競爭(多個線程交替訪問)中等通過 CAS 自旋嘗試獲取鎖,避免操作系統(tǒng)級別的阻塞。
重量級鎖(Heavyweight Lock)高競爭(長時間阻塞或高并發(fā))依賴操作系統(tǒng)互斥量(Mutex),線程被掛起并排隊等待。

3. 鎖升級的過程

鎖升級路徑為:無鎖 → 偏向鎖 → 輕量級鎖 → 重量級鎖,且 不可逆(只能升級,不能降級)。

3.1 無鎖 → 偏向鎖

  • 觸發(fā)條件:第一個線程訪問同步代碼塊時。
  • 過程

    JVM 通過 CAS 操作將對象頭的 Mark Word 標(biāo)記為偏向鎖。

    記錄當(dāng)前線程 ID 和偏向時間戳。

    后續(xù)同一線程再次訪問時,直接通過比對線程 ID 獲取鎖(無需 CAS 操作)。

3.2 偏向鎖 → 輕量級鎖

  • 觸發(fā)條件:第二個線程嘗試獲取同一鎖(出現(xiàn)競爭)。
  • 過程

    偏向鎖失效,JVM 撤銷偏向鎖(可能觸發(fā) STW,Stop-The-World)。

    線程通過自旋(Spin)和 CAS 操作嘗試獲取鎖。

    若自旋成功,則升級為輕量級鎖;否則繼續(xù)自旋或升級為重量級鎖。

3.3 輕量級鎖 → 重量級鎖

  • 觸發(fā)條件
    • 自旋次數(shù)超過閾值(默認(rèn) 10 次,可通過 -XX:PreBlockSpin 調(diào)整)。
    • 多個線程同時競爭鎖(如第三個線程加入競爭)。
  • 過程

    JVM 將鎖升級為重量級鎖,對象頭指向監(jiān)視器(Monitor)。

    線程進(jìn)入操作系統(tǒng)內(nèi)核態(tài)的阻塞隊列,等待調(diào)度器喚醒。

    未獲取鎖的線程通過 ObjectMonitor 等待喚醒。

4. 鎖升級的優(yōu)缺點

4.1 優(yōu)點

  • 減少無競爭場景的開銷:偏向鎖和輕量級鎖避免了頻繁的 CAS 和上下文切換。
  • 動態(tài)適配競爭強(qiáng)度:在低競爭時保持高性能,在高競爭時保證線程安全。

4.2 缺點

  • 偏向鎖撤銷開銷:當(dāng)其他線程競爭時,撤銷偏向鎖會導(dǎo)致 STW,影響性能。
  • 重量級鎖的高開銷:在高競爭場景下,頻繁的線程阻塞/喚醒會顯著降低性能。

5. 鎖升級的優(yōu)化策略

5.1 減少鎖持有時間

  • 優(yōu)化方向:縮短同步代碼塊的執(zhí)行時間,降低鎖的競爭概率。
  • 示例
    // 不推薦:鎖持有時間過長
    synchronized (lock) {
        // 復(fù)雜計算或 IO 操作
    }
    
    // 推薦:僅在關(guān)鍵代碼塊加鎖
    int result = doSomeComputation(); // 非同步操作
    synchronized (lock) {
        sharedVariable = result;
    }
    

5.2 使用分段鎖(Segment Locking)

  • 優(yōu)化方向:將一個大鎖拆分為多個小鎖,減少鎖的競爭范圍。
  • 示例ConcurrentHashMap 使用分段鎖(JDK 8 后改為 CAS + synchronized)。

5.3 禁用偏向鎖

  • 適用場景:頻繁切換線程的場景(如高并發(fā)服務(wù))。
  • JVM 參數(shù)
    -XX:-UseBiasedLocking  # 禁用偏向鎖
    

5.4 調(diào)整自旋次數(shù)

  • 適用場景:輕量級鎖的自旋可能因 CPU 空閑而浪費資源。
  • JVM 參數(shù)
    -XX:PreBlockSpin=5  # 設(shè)置自旋次數(shù)為 5
    

6. 代碼示例

public class LockUpgradeExample {
    private final Object lock = new Object();

    public void performTask() {
        synchronized (lock) {
            // 同步代碼塊
        }
    }

    public static void main(String[] args) {
        LockUpgradeExample example = new LockUpgradeExample();
        Thread t1 = new Thread(example::performTask);
        Thread t2 = new Thread(example::performTask);

        t1.start(); // 初始為偏向鎖(t1)
        t2.start(); // 觸發(fā)偏向鎖撤銷,升級為輕量級鎖
    }
}

7. 關(guān)鍵 JVM 參數(shù)

參數(shù)作用
-XX:+UseBiasedLocking開啟/關(guān)閉偏向鎖(默認(rèn)開啟,Java 15+ 默認(rèn)關(guān)閉)。
-XX:BiasedLockingStartupDelay=0立即啟用偏向鎖(避免延遲)。
-XX:PreBlockSpin設(shè)置輕量級鎖自旋次數(shù)(默認(rèn) 10)。
-XX:-UseSpinning關(guān)閉自旋鎖(強(qiáng)制進(jìn)入重量級鎖)。

8. 總結(jié)

  • 鎖升級是 JVM 自動管理的機(jī)制,開發(fā)者無需手動干預(yù),但理解其原理有助于優(yōu)化并發(fā)性能。
  • 偏向鎖適合單線程場景,輕量級鎖適合低競爭場景,重量級鎖適合高競爭場景。
  • 鎖升級不可逆,一旦升級到重量級鎖,后續(xù)操作將始終使用重量級鎖。

通過合理設(shè)計代碼(如減少鎖粒度、避免過早膨脹到重量級鎖),可以最大化 Java 的并發(fā)性能。

到此這篇關(guān)于Java鎖升級機(jī)制的文章就介紹到這了,更多相關(guān)Java鎖升級機(jī)制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java Set接口及常用實現(xiàn)類總結(jié)

    Java Set接口及常用實現(xiàn)類總結(jié)

    Collection的另一個子接口就是Set,他并沒有我們List常用,并且自身也沒有一些額外的方法,全是繼承自Collection中的,因此我們還是簡單總結(jié)一下,包括他的常用實現(xiàn)類HashSet、LinkedHashSet、TreeSet的總結(jié)
    2023-01-01
  • 解決mybatis plus報錯com.microsoft.sqlserver.jdbc.SQLServerException:必須執(zhí)行該語句才能獲得結(jié)果

    解決mybatis plus報錯com.microsoft.sqlserver.jdbc.SQLServerE

    這篇文章主要介紹了解決mybatis plus報錯com.microsoft.sqlserver.jdbc.SQLServerException:必須執(zhí)行該語句才能獲得結(jié)果,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Spring中WebClient的創(chuàng)建和使用詳解

    Spring中WebClient的創(chuàng)建和使用詳解

    這篇文章主要介紹了Spring中WebClient的創(chuàng)建和使用詳解,在Spring5中,出現(xiàn)了Reactive響應(yīng)式編程思想,并且為網(wǎng)絡(luò)編程提供相關(guān)響應(yīng)式編程的支持,如提供了WebFlux,它是Spring提供的異步非阻塞的響應(yīng)式的網(wǎng)絡(luò)框架,需要的朋友可以參考下
    2023-11-11
  • 詳解Java 包掃描實現(xiàn)和應(yīng)用(Jar篇)

    詳解Java 包掃描實現(xiàn)和應(yīng)用(Jar篇)

    這篇文章主要介紹了詳解Java 包掃描實現(xiàn)和應(yīng)用(Jar篇),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • java實現(xiàn)滑動驗證解鎖

    java實現(xiàn)滑動驗證解鎖

    這篇文章主要為大家詳細(xì)介紹了java實現(xiàn)滑動驗證解鎖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • Java中的適配器原理解析

    Java中的適配器原理解析

    這篇文章主要介紹了Java中的適配器原理解析,當(dāng)實現(xiàn)接口時,為了使所用的類中只實現(xiàn)需要的方法,使代碼更加簡潔,可以定義一個抽象類實現(xiàn)接口,將所需要的方法定義為 抽象方法,然后讓類繼承此抽象方法即可,需要的朋友可以參考下
    2023-11-11
  • 為什么說HashMap線程不安全

    為什么說HashMap線程不安全

    本文主要介紹了為什么說HashMap線程不安全,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Java使用jdbc連接實現(xiàn)對MySQL增刪改查操作的全過程

    Java使用jdbc連接實現(xiàn)對MySQL增刪改查操作的全過程

    JDBC的全稱是Java?Database?Connectivity,即Java數(shù)據(jù)庫連接,它是一種可以執(zhí)行SQL語句的Java?API,下面這篇文章主要給大家介紹了關(guān)于Java使用jdbc連接實現(xiàn)對MySQL增刪改查操作的相關(guān)資料,需要的朋友可以參考下
    2023-03-03
  • Java使用OTP動態(tài)口令(每分鐘變一次)進(jìn)行登錄認(rèn)證

    Java使用OTP動態(tài)口令(每分鐘變一次)進(jìn)行登錄認(rèn)證

    這篇文章主要介紹了Java使用OTP動態(tài)口令(每分鐘變一次)進(jìn)行登錄認(rèn)證,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Java 遍歷取出Map集合key-value數(shù)據(jù)的4種方法

    Java 遍歷取出Map集合key-value數(shù)據(jù)的4種方法

    這篇文章主要介紹了Java 遍歷取出Map集合key-value數(shù)據(jù)的4種方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09

最新評論