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

synchronized?vs?ReentrantLock性能對(duì)比:哪個(gè)更適合高并發(fā)場(chǎng)景?

 更新時(shí)間:2026年07月25日 13:50:42   作者:小假是真的  
還在糾結(jié)synchronized和ReentrantLock怎么選?本文深入對(duì)比Java并發(fā)編程中這兩種鎖的實(shí)現(xiàn)機(jī)制、使用方式、公平性、條件變量、中斷與超時(shí)等關(guān)鍵區(qū)別,并給出面試和實(shí)際開(kāi)發(fā)中的選擇建議,幫你徹底搞懂并發(fā)編程核心知識(shí)點(diǎn)

一、基本特性對(duì)比

特性

synchronized

ReentrantLock

鎖的實(shí)現(xiàn)機(jī)制

JVM 內(nèi)置關(guān)鍵字,通過(guò)監(jiān)視器實(shí)現(xiàn)

JDK 提供的 API 類(lèi)(java.util.concurrent.locks

鎖的獲取方式

隱式獲取和釋放(進(jìn)入/退出同步代碼塊或方法自動(dòng)獲取/釋放)

顯式調(diào)用 lock()/unlock()方法

可重入性

支持

支持

鎖的類(lèi)型

非公平鎖(默認(rèn))

可選擇公平鎖或非公平鎖(構(gòu)造函數(shù)指定)

條件變量

通過(guò) wait()/notify()/notifyAll()實(shí)現(xiàn)

通過(guò) Condition對(duì)象支持多個(gè)條件隊(duì)列

中斷響應(yīng)

不支持中斷等待

支持 lockInterruptibly()中斷等待

超時(shí)機(jī)制

不支持

支持 tryLock(timeout, unit)嘗試獲取鎖

鎖的綁定

與代碼塊或方法綁定

可跨方法綁定,更靈活

性能

JDK 1.6 后優(yōu)化,性能接近

在高并發(fā)競(jìng)爭(zhēng)下表現(xiàn)更穩(wěn)定

二、詳細(xì)區(qū)別分析

1. 實(shí)現(xiàn)層面

  • synchronized
    • Java 關(guān)鍵字,由 JVM 底層實(shí)現(xiàn)(通過(guò) monitorenter/monitorexit 字節(jié)碼指令)。
    • 鎖信息記錄在對(duì)象頭的 Mark Word 中。
  • ReentrantLock
    • 基于 AbstractQueuedSynchronizer(AQS) 實(shí)現(xiàn)的顯式鎖。
    • 通過(guò) CAS(Compare-And-Swap)和隊(duì)列管理線程競(jìng)爭(zhēng)。

2. 使用方式

// synchronized 隱式使用
public synchronized void method() {
    // 同步代碼
}
// 或
public void method() {
    synchronized(this) {
        // 同步代碼
    }
}

// ReentrantLock 顯式使用
private ReentrantLock lock = new ReentrantLock();
public void method() {
    lock.lock();
    try {
        // 同步代碼
    } finally {
        lock.unlock(); // 必須手動(dòng)釋放
    }
}

3. 公平性選擇

  • synchronized:僅支持非公平鎖(線程競(jìng)爭(zhēng)時(shí)隨機(jī)獲取鎖)。
  • ReentrantLock
    • 公平鎖:按等待時(shí)間順序獲取鎖,避免線程饑餓,但性能較低。
    • 非公平鎖:允許插隊(duì),性能更高。

4. 條件變量(Condition)

  • synchronized:通過(guò) Object.wait()/notify() 實(shí)現(xiàn)等待/喚醒,只能有一個(gè)等待隊(duì)列。
  • ReentrantLock:可創(chuàng)建多個(gè) Condition 對(duì)象,實(shí)現(xiàn)精細(xì)化的線程等待/喚醒。
Condition condition = lock.newCondition();
condition.await();      // 類(lèi)似 wait()
condition.signal();     // 類(lèi)似 notify()

示例:生產(chǎn)者-消費(fèi)者模型中,可為空隊(duì)列和滿隊(duì)列分別設(shè)置 Condition。

5. 中斷與超時(shí)

  • synchronized
    • 線程等待鎖時(shí)無(wú)法被中斷。
    • 無(wú)超時(shí)機(jī)制,可能永久等待。
  • ReentrantLock
// 支持中斷
lock.lockInterruptibly();

// 支持超時(shí)
if (lock.tryLock(1, TimeUnit.SECONDS)) {
    try { /* 操作 */ } 
    finally { lock.unlock(); }
}

6. 性能差異

  • JDK 1.5 時(shí) ReentrantLock 性能顯著優(yōu)于 synchronized。
  • JDK 1.6 后 JVM 對(duì) synchronized 進(jìn)行了大量?jī)?yōu)化(鎖升級(jí)、自適應(yīng)自旋等),兩者性能差距縮小。
  • 在高競(jìng)爭(zhēng)場(chǎng)景下,ReentrantLock 仍可能表現(xiàn)更穩(wěn)定。

三、適用場(chǎng)景

優(yōu)先使用 synchronized 的情況

  • 簡(jiǎn)單的同步場(chǎng)景,代碼簡(jiǎn)潔性更重要。
  • 不需要高級(jí)功能(如條件變量、中斷、超時(shí))。
  • 資源競(jìng)爭(zhēng)不激烈時(shí),性能可接受。

優(yōu)先使用 ReentrantLock 的情況

  • 需要公平鎖、可中斷鎖、超時(shí)鎖等高級(jí)功能。
  • 需要多個(gè)條件變量(如阻塞隊(duì)列的實(shí)現(xiàn))。
  • 需要跨方法加鎖/釋放鎖(如:在方法 A 加鎖,在方法 B 釋放)。
  • 競(jìng)爭(zhēng)激烈且性能要求高。

四、示例對(duì)比

場(chǎng)景:生產(chǎn)者-消費(fèi)者模型

// 使用 synchronized(單一條件)
public synchronized void put(Object item) throws InterruptedException {
    while (queue.isFull()) {
        wait(); // 只能在一個(gè)條件上等待
    }
    queue.put(item);
    notifyAll();
}

// 使用 ReentrantLock(多條件)
private final Lock lock = new ReentrantLock();
private final Condition notFull = lock.newCondition();
private final Condition notEmpty = lock.newCondition();

public void put(Object item) throws InterruptedException {
    lock.lock();
    try {
        while (queue.isFull()) {
            notFull.await(); // 只在 "非滿" 條件上等待
        }
        queue.put(item);
        notEmpty.signal();   // 只喚醒等待 "非空" 的線程
    } finally {
        lock.unlock();
    }
}

五、總結(jié)

  • synchronized 簡(jiǎn)單、安全、自動(dòng)管理鎖釋放,適合大多數(shù)常規(guī)同步場(chǎng)景。
  • ReentrantLock 功能強(qiáng)大、靈活可控,適合復(fù)雜并發(fā)場(chǎng)景和高級(jí)需求。
  • 從 JDK 1.6 開(kāi)始,兩者性能接近,選擇時(shí)應(yīng)更關(guān)注功能需求代碼可維護(hù)性
  • 在 JDK 后續(xù)版本中,synchronized 仍在持續(xù)優(yōu)化(如鎖消除、鎖粗化等),而 ReentrantLock 提供了更細(xì)粒度的并發(fā)控制。

面試回答

首先,synchronized 是 Java 語(yǔ)言層面的關(guān)鍵字,是 JVM 原生支持的鎖機(jī)制。它的使用非常簡(jiǎn)單,編譯器會(huì)自動(dòng)處理鎖的獲取和釋放,所以基本不會(huì)因?yàn)橥涐尫沛i而導(dǎo)致死鎖,易用性是它的最大優(yōu)點(diǎn)
ReentrantLockJUC 包下的一個(gè)類(lèi),是 JDK 層面實(shí)現(xiàn)的鎖。它需要開(kāi)發(fā)者顯式地調(diào)用 lock()unlock() 方法,通常在 finally 塊中釋放鎖,否則容易出問(wèn)題。所以從使用門(mén)檻上說(shuō),synchronized 更低。

在功能上,ReentrantLocksynchronized 靈活和強(qiáng)大得多,主要有三點(diǎn):

  1. 可中斷獲取鎖:當(dāng)線程嘗試獲取 ReentrantLock 時(shí),如果長(zhǎng)時(shí)間拿不到,可以響應(yīng)中斷,通過(guò) lockInterruptibly() 方法放棄等待去做別的事情。而 synchronized 在等待鎖時(shí),線程會(huì)一直阻塞,無(wú)法被中斷。
  2. 公平鎖選項(xiàng)ReentrantLock 可以在構(gòu)造函數(shù)中指定是否是公平鎖(先等待的線程先獲得鎖)。雖然公平鎖性能有損耗,但能防止線程饑餓。synchronized 則是非公平的,誰(shuí)搶到算誰(shuí)的,性能通常更好。
  3. 條件變量(Condition):這是非常強(qiáng)大的一點(diǎn)。一個(gè) ReentrantLock 可以創(chuàng)建多個(gè) Condition 對(duì)象,用來(lái)實(shí)現(xiàn)更精細(xì)的線程等待/通知。比如,我們可以讓一部分線程在條件A上等待,另一部分在條件B上等待,喚醒時(shí)也可以選擇只喚醒等待條件A的線程。而 synchronized 只能配合 wait()notify(),所有線程都在同一個(gè)條件隊(duì)列上,喚醒是隨機(jī)的(notify)或全部喚醒(notifyAll),不夠精確。

在早期版本(JDK 1.5 之前),ReentrantLock 的性能比 synchronized 好很多。但后來(lái) JVM 對(duì) synchronized 進(jìn)行了大幅優(yōu)化,比如引入了偏向鎖、輕量級(jí)鎖、自旋鎖、鎖消除、鎖粗化等。所以在高版本的 JDK(如 1.8 及以后)中,兩者在性能上已經(jīng)相差無(wú)幾,synchronized 甚至在一些常見(jiàn)場(chǎng)景下更優(yōu),因?yàn)樗?JVM 的持續(xù)優(yōu)化。

所以,我的選擇原則通常是:

  • 優(yōu)先考慮 synchronized:在滿足需求的情況下,因?yàn)樗?jiǎn)單、安全(自動(dòng)釋放),且性能不差。大部分標(biāo)準(zhǔn)的同步場(chǎng)景用它就夠了。
  • 需要高級(jí)功能時(shí)再用 ReentrantLock:比如我需要用到可中斷、公平鎖,或者需要復(fù)雜的條件等待機(jī)制(典型應(yīng)用就是“生產(chǎn)者-消費(fèi)者”模型),這時(shí) ReentrantLock 是唯一的選擇。

到此這篇關(guān)于synchronized vs ReentrantLock性能對(duì)比:哪個(gè)更適合高并發(fā)場(chǎng)景?的文章就介紹到這了,更多相關(guān)synchronized和ReentrantLock的區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java常見(jiàn)的字符串拼接方式總結(jié)

    java常見(jiàn)的字符串拼接方式總結(jié)

    這篇文章主要為大家詳細(xì)介紹了java中常見(jiàn)的字符串拼接方式,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-09-09
  • SpringBoot利用redis集成消息隊(duì)列的方法

    SpringBoot利用redis集成消息隊(duì)列的方法

    這篇文章主要介紹了SpringBoot利用redis集成消息隊(duì)列的方法,需要的朋友可以參考下
    2017-08-08
  • Java長(zhǎng)字符串加密的實(shí)現(xiàn)

    Java長(zhǎng)字符串加密的實(shí)現(xiàn)

    在Java中,字符串是一種常見(jiàn)的數(shù)據(jù)類(lèi)型,我們經(jīng)常需要對(duì)其進(jìn)行加密和解密,本文主要介紹了Java長(zhǎng)字符串加密的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02
  • springboot使用redisTemplate操作lua腳本

    springboot使用redisTemplate操作lua腳本

    本文主要介紹了springboot使用redisTemplate操作lua腳本,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • springcloud使用feign調(diào)用服務(wù)時(shí)參數(shù)內(nèi)容過(guò)大問(wèn)題

    springcloud使用feign調(diào)用服務(wù)時(shí)參數(shù)內(nèi)容過(guò)大問(wèn)題

    這篇文章主要介紹了springcloud使用feign調(diào)用服務(wù)時(shí)參數(shù)內(nèi)容過(guò)大問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • MyBatisPlus用JavaBean映射數(shù)據(jù)庫(kù)表及樂(lè)觀鎖實(shí)戰(zhàn)指南

    MyBatisPlus用JavaBean映射數(shù)據(jù)庫(kù)表及樂(lè)觀鎖實(shí)戰(zhàn)指南

    本文主要介紹了MyBatis-Plus查詢中映射匹配兼容性相關(guān)概念,以及當(dāng)表字段與編碼屬性設(shè)計(jì)不同步時(shí)的解決辦法和JavaBean在MyBatis-Plus中的作用;同時(shí)講述了主鍵id生成策略控制、多記錄操作、邏輯刪除以及樂(lè)觀鎖等操作的實(shí)現(xiàn)方式
    2026-04-04
  • springcloud項(xiàng)目里application.yml不加載的坑及解決

    springcloud項(xiàng)目里application.yml不加載的坑及解決

    這篇文章主要介紹了springcloud項(xiàng)目里application.yml不加載的坑及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • java實(shí)現(xiàn)線程調(diào)度器和時(shí)間分片

    java實(shí)現(xiàn)線程調(diào)度器和時(shí)間分片

    線程調(diào)度器和時(shí)間分片是多線程編程和操作系統(tǒng)設(shè)計(jì)中的核心概念,本文主要介紹了java實(shí)現(xiàn)線程調(diào)度器和時(shí)間分片,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-10-10
  • Java實(shí)現(xiàn)讀取Jar文件屬性的方法詳解

    Java實(shí)現(xiàn)讀取Jar文件屬性的方法詳解

    這篇文章主要為大家詳細(xì)介紹了如何利用Java語(yǔ)言實(shí)現(xiàn)讀取Jar文件屬性的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-08-08
  • Mybatis控制臺(tái)打印Sql語(yǔ)句的實(shí)現(xiàn)代碼

    Mybatis控制臺(tái)打印Sql語(yǔ)句的實(shí)現(xiàn)代碼

    MyBatis是一個(gè)支持普通SQL查詢,存儲(chǔ)過(guò)程和高級(jí)映射的優(yōu)秀持久層框架,下面給大家介紹Mybatis控制臺(tái)打印Sql語(yǔ)句的實(shí)現(xiàn)代碼,非常不錯(cuò),感興趣的朋友一起看下吧
    2016-07-07

最新評(píng)論

岳阳县| 芦溪县| 姜堰市| 平塘县| 宣武区| 荥经县| 海盐县| 潍坊市| 静乐县| 大厂| 曲周县| 基隆市| 兰溪市| 循化| 集贤县| 罗平县| 河曲县| 滁州市| 固阳县| 德令哈市| 万源市| 克什克腾旗| 沈阳市| 仙桃市| 元阳县| 怀来县| 孝义市| 大田县| 胶南市| 兴山县| 武宣县| 石阡县| 从化市| 婺源县| 福安市| 罗山县| 榆树市| 四子王旗| 成安县| 大余县| 喀什市|