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

一文帶你認(rèn)識(shí)Java中的鎖升級(jí)機(jī)制

 更新時(shí)間:2025年12月21日 15:35:51   作者:篤行客從不躺平  
在Java中鎖升級(jí)是一種重要的性能優(yōu)化機(jī)制,用于提高多線程環(huán)境下并發(fā)訪問(wèn)的效率,這篇文章主要介紹了Java中鎖級(jí)機(jī)制的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下

一、鎖升級(jí)的本質(zhì):JVM 的“自適應(yīng)并發(fā)優(yōu)化”

核心思想
大多數(shù)鎖在運(yùn)行時(shí)沒(méi)有競(jìng)爭(zhēng),或競(jìng)爭(zhēng)時(shí)間極短。與其一開(kāi)始就使用重量級(jí)鎖,不如先嘗試更輕量的方式。

鎖狀態(tài)演進(jìn)路徑(HotSpot 64位 JVM)

無(wú)鎖 → 偏向鎖(Biased Locking) → 輕量級(jí)鎖(Lightweight Locking) → 重量級(jí)鎖(Heavyweight Locking)

?? 關(guān)鍵特性:

  • 單向升級(jí):鎖只能升級(jí),不能降級(jí)(除 GC 或顯式撤銷(xiāo))
  • 基于對(duì)象頭 Mark Word 狀態(tài)切換
  • 由 JVM 自動(dòng)決策,開(kāi)發(fā)者無(wú)需干預(yù)

二、深入原理 + 場(chǎng)景 + 代碼示例

1. 偏向鎖(Biased Locking)—— 單線程的極致優(yōu)化

底層原理

  • 對(duì)象頭 Mark Word 中存儲(chǔ) 偏向線程 ID
  • 同一線程再次進(jìn)入同步塊時(shí),僅比對(duì)線程 ID,無(wú)需 CAS
  • 若對(duì)象未計(jì)算過(guò) hashCode,則用 hashcode 字段存儲(chǔ)線程 ID

Mark Word 結(jié)構(gòu)(偏向鎖狀態(tài))

| unused:25 | thread_id:54 | epoch:2 | age:4 | biased_lock:1 | lock:01 |

典型場(chǎng)景

  • Spring 單例 Bean 中的 synchronized 方法被同一線程反復(fù)調(diào)用
  • 批處理任務(wù)(如定時(shí)對(duì)賬、數(shù)據(jù)清洗)

代碼示例 & 驗(yàn)證

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

    public void processBatch(List<Data> dataList) {
        // 同一線程循環(huán)進(jìn)入,觸發(fā)偏向鎖
        for (Data data : dataList) {
            synchronized (lock) {
                // 業(yè)務(wù)邏輯
                handle(data);
            }
        }
    }

    // 注意:若在此處調(diào)用 lock.hashCode(),會(huì)禁用偏向鎖!
}

? 性能優(yōu)勢(shì):接近無(wú)鎖,僅首次 CAS 設(shè)置偏向,后續(xù)零開(kāi)銷(xiāo)。
? 致命缺陷:偏向鎖撤銷(xiāo)需 Stop-The-World(STW),影響延遲敏感系統(tǒng)。

2. 輕量級(jí)鎖(Lightweight Locking)—— 低競(jìng)爭(zhēng)的優(yōu)雅退讓

底層原理

  • 當(dāng)?shù)诙€(gè)線程嘗試獲取已被偏向的鎖時(shí),撤銷(xiāo)偏向鎖
  • 線程在棧幀中創(chuàng)建 Lock Record
  • 通過(guò) CAS 將對(duì)象頭 Mark Word 替換為指向 Lock Record 的指針
  • 若 CAS 失敗,線程自旋重試(默認(rèn) 10 次),失敗則膨脹為重量級(jí)鎖

典型場(chǎng)景

  • Web 請(qǐng)求處理(低并發(fā)、請(qǐng)求串行化)
  • 日志寫(xiě)入(多線程交替寫(xiě),但不同時(shí))

代碼示例

@RestController
public class OrderController {
    private final Object orderLock = new Object();
    
    @PostMapping("/create")
    public ResponseEntity<?> createOrder(@RequestBody OrderRequest req) {
        synchronized (orderLock) { // 多個(gè)請(qǐng)求線程交替進(jìn)入
            validate(req);
            return orderService.create(req);
        }
    }
}

? 優(yōu)勢(shì):避免線程阻塞/喚醒的系統(tǒng)調(diào)用開(kāi)銷(xiāo)(上下文切換成本約 1~10μs)
? 風(fēng)險(xiǎn):自旋浪費(fèi) CPU,在 CPU 密集型場(chǎng)景可能惡化性能

3. 重量級(jí)鎖(Heavyweight Locking)—— 高競(jìng)爭(zhēng)的最終保障

底層原理

  • 基于 OS Mutex(互斥量) 實(shí)現(xiàn)
  • 競(jìng)爭(zhēng)線程被掛起(park()),放入 EntryList 隊(duì)列
  • 持有鎖線程釋放時(shí),喚醒隊(duì)列中的一個(gè)線程(unpark()
  • 涉及 用戶態(tài) ↔ 內(nèi)核態(tài)切換,開(kāi)銷(xiāo)大(約 1~10μs)

典型場(chǎng)景

  • 秒殺庫(kù)存扣減
  • 全局配置更新
  • 數(shù)據(jù)庫(kù)連接池管理

反面教材 vs 正確做法

// ? 反面:synchronized 導(dǎo)致重量級(jí)鎖競(jìng)爭(zhēng)
public class InventoryService {
    private int stock = 100;
    public synchronized boolean deduct() {
        if (stock > 0) {
            stock--; // 高并發(fā)下性能極差
            return true;
        }
        return false;
    }
}

// ? 正確:使用 LongAdder(分段無(wú)鎖)
public class OptimizedInventory {
    private final LongAdder deducted = new LongAdder();
    private final int totalStock = 100;
    
    public boolean deduct() {
        long current = deducted.sum();
        if (current >= totalStock) return false;
        deducted.increment(); // 無(wú)鎖,分段累加
        return true;
    }
}

三、生產(chǎn)環(huán)境實(shí)戰(zhàn):如何應(yīng)用與調(diào)優(yōu)?

生產(chǎn)最佳實(shí)踐

場(chǎng)景推薦方案原理
微服務(wù)高并發(fā)關(guān)閉偏向鎖避免頻繁撤銷(xiāo)導(dǎo)致 STW
計(jì)數(shù)器/狀態(tài)LongAdder / AtomicXXX分段無(wú)鎖,避免全局競(jìng)爭(zhēng)
讀多寫(xiě)少StampedLock樂(lè)觀讀,提升吞吐
復(fù)雜同步邏輯ReentrantLock + Condition支持超時(shí)、中斷、公平鎖

JVM 參數(shù)調(diào)優(yōu)(生產(chǎn)常用)

# 關(guān)閉偏向鎖(推薦微服務(wù)場(chǎng)景)
-XX:-UseBiasedLocking

# 禁用偏向鎖延遲(啟動(dòng)即生效)
-XX:BiasedLockingStartupDelay=0

# 監(jiān)控鎖統(tǒng)計(jì)(診斷用)
-XX:+PrintBiasedLockingStatistics
-XX:+UnlockDiagnosticVMOptions -XX:+PrintSafepointStatistics

# 調(diào)整自旋次數(shù)(謹(jǐn)慎?。?
-XX:PreBlockSpin=15

?? 真實(shí)案例
某電商平臺(tái)在大促前發(fā)現(xiàn) GC Pause 異常升高,經(jīng) JFR 分析發(fā)現(xiàn) 偏向鎖撤銷(xiāo)頻繁觸發(fā) safepoint。關(guān)閉 -XX:-UseBiasedLocking 后,P99 延遲下降 40%。

四、優(yōu)缺點(diǎn)深度分析

鎖類(lèi)型優(yōu)點(diǎn)缺點(diǎn)適用邊界
偏向鎖單線程零開(kāi)銷(xiāo)撤銷(xiāo)需 STW,不適合多線程交替單線程長(zhǎng)期持有(< 1% 生產(chǎn)場(chǎng)景)
輕量級(jí)鎖避免內(nèi)核切換自旋浪費(fèi) CPU,僅適合短臨界區(qū)低競(jìng)爭(zhēng) + 臨界區(qū) < 10μs
重量級(jí)鎖強(qiáng)一致性保障上下文切換開(kāi)銷(xiāo)大高競(jìng)爭(zhēng)或長(zhǎng)臨界區(qū)

?? 關(guān)鍵洞察
鎖升級(jí)是 JVM 的“事后補(bǔ)救”機(jī)制。真正的高性能系統(tǒng)應(yīng)從架構(gòu)層面避免鎖競(jìng)爭(zhēng),而非依賴鎖優(yōu)化。

五、實(shí)際開(kāi)發(fā)選型策略 —— 高級(jí)工程師思維

決策樹(shù)(體現(xiàn)深度)

高級(jí)建議(面試加分項(xiàng))

  1. 優(yōu)先無(wú)鎖:使用 volatile + CAS(如 AtomicReference
  2. 縮小鎖粒度:只鎖臨界區(qū),而非整個(gè)方法
    // Bad
    public synchronized void method() { /* ... */ }
    
    // Good
    public void method() {
        // 非臨界區(qū)
        prepare();
        synchronized (this) {
            // 臨界區(qū)
        }
    }
  3. 監(jiān)控鎖競(jìng)爭(zhēng):使用 Arthas、JFR 分析
    # Arthas 查看 BLOCKED 線程
    thread --state BLOCKED
    
    # JFR 記錄鎖事件
    java -XX:StartFlightRecording=duration=60s,filename=lock.jfr ...

六、面試深度

Q1: 為什么現(xiàn)代微服務(wù)要關(guān)閉偏向鎖?

:微服務(wù)使用線程池復(fù)用線程,多個(gè)請(qǐng)求線程交替訪問(wèn)同一對(duì)象,導(dǎo)致偏向鎖頻繁撤銷(xiāo)。而撤銷(xiāo)需觸發(fā) safepoint(STW),在高 QPS 下會(huì)顯著增加 P99 延遲。Kafka、Netty 等高性能框架均默認(rèn)關(guān)閉。

Q2: synchronized 和 ReentrantLock 在 JDK 17 下性能對(duì)比?

:JDK 6+ 對(duì) synchronized 進(jìn)行了鎖消除、鎖粗化、鎖升級(jí)等優(yōu)化,在低競(jìng)爭(zhēng)場(chǎng)景性能優(yōu)于 ReentrantLock(后者始終走重量級(jí)路徑)。但 ReentrantLock 提供更多功能(超時(shí)、公平鎖、Condition),適用于復(fù)雜同步場(chǎng)景。

Q3: 如何證明鎖升級(jí)發(fā)生了?

:可通過(guò)以下方式驗(yàn)證:

  1. 使用 JOL(Java Object Layout) 打印對(duì)象頭
  2. 開(kāi)啟 JVM 參數(shù) -XX:+PrintBiasedLockingStatistics
  3. 使用 JFR(Java Flight Recorder) 記錄 Monitor Blocked 事件

總結(jié):高級(jí)工程師的并發(fā)觀

鎖升級(jí)是 JVM 的“安全網(wǎng)”,但真正的高手從不依賴安全網(wǎng)。應(yīng)該:

  • 理解原理:知道 JVM 如何優(yōu)化,也知其局限
  • 規(guī)避競(jìng)爭(zhēng):通過(guò)無(wú)狀態(tài)設(shè)計(jì)、分片、異步化減少鎖需求
  • 工具驅(qū)動(dòng):用 JFR、Arthas 驗(yàn)證假設(shè),而非猜測(cè)
  • 權(quán)衡取舍:在一致性、性能、復(fù)雜度間找到平衡點(diǎn)

“最好的并發(fā)控制,是沒(méi)有并發(fā)控制。”
—— 通過(guò)架構(gòu)設(shè)計(jì)從根本上消滅鎖,才是高級(jí)工程師的終極追求。

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

相關(guān)文章

  • protobuf簡(jiǎn)介及使用流程

    protobuf簡(jiǎn)介及使用流程

    本文介紹了Protocol Buffers(protobuf)的數(shù)據(jù)結(jié)構(gòu)序列化和反序列化框架,包括其特點(diǎn)、使用流程和快速上手,通過(guò)一個(gè)簡(jiǎn)單的通訊錄示例,展示了如何創(chuàng)建.proto文件、添加注釋、編寫(xiě)消息定義、編譯.proto文件以及進(jìn)行序列化和反序列化操作,感興趣的朋友一起看看吧
    2025-02-02
  • Springboot FatJa原理機(jī)制源碼解析

    Springboot FatJa原理機(jī)制源碼解析

    這篇文章主要為大家介紹了Springboot FatJa原理機(jī)制源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • JAVA 多線程之信號(hào)量(Semaphore)實(shí)例詳解

    JAVA 多線程之信號(hào)量(Semaphore)實(shí)例詳解

    這篇文章主要介紹了JAVA 多線程之信號(hào)量(Semaphore)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • SpringBoot集成Access?DB實(shí)現(xiàn)數(shù)據(jù)導(dǎo)入和解析

    SpringBoot集成Access?DB實(shí)現(xiàn)數(shù)據(jù)導(dǎo)入和解析

    microsoft?office?access是由微軟發(fā)布的關(guān)聯(lián)式數(shù)據(jù)庫(kù)管理系統(tǒng),它結(jié)合了?microsoft?jet?database?engine?和?圖形用戶界面兩項(xiàng)特點(diǎn),是一種關(guān)系數(shù)據(jù)庫(kù)工具,本文給大家介紹了SpringBoot集成Access?DB實(shí)現(xiàn)數(shù)據(jù)導(dǎo)入和解析,需要的朋友可以參考下
    2024-11-11
  • Spring Boot中數(shù)據(jù)庫(kù)操作Druid和HikariDataSource的詳細(xì)過(guò)程

    Spring Boot中數(shù)據(jù)庫(kù)操作Druid和HikariDataSource的詳細(xì)過(guò)程

    這篇文章主要介紹了Spring Boot中數(shù)據(jù)庫(kù)操作Druid和HikariDataSource的詳細(xì)過(guò)程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-06-06
  • java編程簡(jiǎn)單獲取圖片像素的方法

    java編程簡(jiǎn)單獲取圖片像素的方法

    這篇文章主要介紹了java編程簡(jiǎn)單獲取圖片像素的方法,涉及Java針對(duì)圖片的讀取與屬性獲取技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-11-11
  • 在java List中進(jìn)行模糊查詢的實(shí)現(xiàn)方法

    在java List中進(jìn)行模糊查詢的實(shí)現(xiàn)方法

    下面小編就為大家?guī)?lái)一篇在java List中進(jìn)行模糊查詢的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-11-11
  • springboot使JUL實(shí)現(xiàn)日志管理功能

    springboot使JUL實(shí)現(xiàn)日志管理功能

    這篇文章主要介紹了springboot使JUL實(shí)現(xiàn)日志管理功能,本文分步驟給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • 一文詳解Spring任務(wù)執(zhí)行和調(diào)度(小結(jié))

    一文詳解Spring任務(wù)執(zhí)行和調(diào)度(小結(jié))

    這篇文章主要介紹了一文詳解Spring任務(wù)執(zhí)行和調(diào)度(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Java中時(shí)間戳的獲取和轉(zhuǎn)換的示例分析

    Java中時(shí)間戳的獲取和轉(zhuǎn)換的示例分析

    這篇文章主要介紹了Java中時(shí)間戳的獲取和轉(zhuǎn)換的示例分析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評(píng)論

玛曲县| 上犹县| 镇安县| 漳州市| 昌黎县| 额尔古纳市| 桑植县| 石阡县| 礼泉县| 密云县| 灵宝市| 巴东县| 九寨沟县| 玛纳斯县| 手游| 太原市| 米易县| 宜君县| 台江县| 宁远县| 昌图县| 景谷| 秭归县| 哈尔滨市| 嘉定区| 体育| 夏津县| 桦甸市| 亳州市| 永昌县| 天台县| 延川县| 桑植县| 房产| 岱山县| 青河县| 阜阳市| 长丰县| 勃利县| 墨竹工卡县| 武城县|