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

Java中synchronized和ReentrantLock的區(qū)別對比

 更新時間:2026年01月02日 09:02:26   作者:程序員小假  
這篇文章主要介紹了Java中synchronized和ReentrantLock的區(qū)別對比,synchronized和ReentrantLock是Java中兩種主要的線程同步機制,它們都能保證線程安全,但在實現(xiàn)和功能上有明顯區(qū)別,需要的朋友可以參考下本篇介紹

一、基本特性對比

特性synchronizedReentrantLock
鎖的實現(xiàn)機制JVM 內(nèi)置關(guān)鍵字,通過監(jiān)視器實現(xiàn)JDK 提供的 API 類(java.util.concurrent.locks)
鎖的獲取方式隱式獲取和釋放(進(jìn)入/退出同步代碼塊或方法自動獲取/釋放)顯式調(diào)用 lock()/unlock()方法
可重入性支持支持
鎖的類型非公平鎖(默認(rèn))可選擇公平鎖或非公平鎖(構(gòu)造函數(shù)指定)
條件變量通過 wait()/notify()/notifyAll()實現(xiàn)通過 Condition對象支持多個條件隊列
中斷響應(yīng)不支持中斷等待支持 lockInterruptibly()中斷等待
超時機制不支持支持 tryLock(timeout, unit)嘗試獲取鎖
鎖的綁定與代碼塊或方法綁定可跨方法綁定,更靈活
性能JDK 1.6 后優(yōu)化,性能接近在高并發(fā)競爭下表現(xiàn)更穩(wěn)定

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

1. 實現(xiàn)層面

synchronized:

  • Java 關(guān)鍵字,由 JVM 底層實現(xiàn)(通過 monitorenter/monitorexit 字節(jié)碼指令)。
  • 鎖信息記錄在對象頭的 Mark Word 中。

ReentrantLock:

  • 基于 AbstractQueuedSynchronizer(AQS) 實現(xiàn)的顯式鎖。
  • 通過 CAS(Compare-And-Swap)和隊列管理線程競爭。

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(); // 必須手動釋放
    }
}

3. 公平性選擇

synchronized:僅支持非公平鎖(線程競爭時隨機獲取鎖)。

ReentrantLock:

  • 公平鎖:按等待時間順序獲取鎖,避免線程饑餓,但性能較低。
  • 非公平鎖:允許插隊,性能更高。

4. 條件變量(Condition)

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

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

5. 中斷與超時

synchronized:

  • 線程等待鎖時無法被中斷。
  • 無超時機制,可能永久等待。

ReentrantLock:

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

6. 性能差異

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

三、適用場景

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

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

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

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

四、示例對比

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

// 使用 synchronized(單一條件)
public synchronized void put(Object item) throws InterruptedException {
    while (queue.isFull()) {
        wait(); // 只能在一個條件上等待
    }
    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 簡單、安全、自動管理鎖釋放,適合大多數(shù)常規(guī)同步場景。
  • ReentrantLock 功能強大、靈活可控,適合復(fù)雜并發(fā)場景和高級需求。
  • 從 JDK 1.6 開始,兩者性能接近,選擇時應(yīng)更關(guān)注功能需求和代碼可維護(hù)性。
  • 在 JDK 后續(xù)版本中,synchronized 仍在持續(xù)優(yōu)化(如鎖消除、鎖粗化等),而 ReentrantLock 提供了更細(xì)粒度的并發(fā)控制。

面試回答

首先,synchronized 是 Java 語言層面的關(guān)鍵字,是 JVM 原生支持的鎖機制。它的使用非常簡單,編譯器會自動處理鎖的獲取和釋放,所以基本不會因為忘記釋放鎖而導(dǎo)致死鎖,易用性是它的最大優(yōu)點。

而 ReentrantLock 是 JUC 包下的一個類,是 JDK 層面實現(xiàn)的鎖。它需要開發(fā)者顯式地調(diào)用 lock() 和 unlock() 方法,通常在 finally 塊中釋放鎖,否則容易出問題。所以從使用門檻上說,synchronized 更低。

在功能上,ReentrantLock 比 synchronized 靈活和強大得多,主要有三點:

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

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

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

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

以上就是Java中synchronized和ReentrantLock的區(qū)別對比的詳細(xì)內(nèi)容,更多關(guān)于Java synchronized與ReentrantLock的資料請關(guān)注腳本之家其它相關(guān)文章!

  • 計算兩個字符串最大公有子串

    計算兩個字符串最大公有子串

    本文主要介紹了計算兩個字符串最大公有子串的解決方案。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-01-01
  • Spring高級接口Aware淺析

    Spring高級接口Aware淺析

    通過aware接口可以獲取Spring容器相關(guān)信息,但這樣會與Spring容器耦合,這篇文章主要介紹了Spring aware接口理解,需要的朋友可以參考下
    2023-01-01
  • Spring Scheduler定時任務(wù)實戰(zhàn)指南(零基礎(chǔ)入門任務(wù)調(diào)度)

    Spring Scheduler定時任務(wù)實戰(zhàn)指南(零基礎(chǔ)入門任務(wù)調(diào)度)

    本文介紹SpringScheduler在電商訂單超時處理中的應(yīng)用,涵蓋啟用定時任務(wù)、使用@Scheduled注解、cron表達(dá)式配置、線程池優(yōu)化及異步執(zhí)行等核心內(nèi)容,本文給大家介紹Spring Scheduler定時任務(wù)實戰(zhàn)指南,感興趣的朋友跟隨小編一起看看吧
    2025-09-09
  • IntelliJ IDEA設(shè)置代碼的快捷編輯模板Live Templates

    IntelliJ IDEA設(shè)置代碼的快捷編輯模板Live Templates

    今天小編就為大家分享一篇關(guān)于IntelliJ IDEA設(shè)置代碼的快捷編輯模板Live Templates,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • Java猴子吃桃問題

    Java猴子吃桃問題

    這篇文章主要介紹了Java猴子吃桃問題,采取逆向思維的方法,從后往前推斷,需要的朋友可以參考下
    2017-02-02
  • Java責(zé)任鏈模式模板代碼分享

    Java責(zé)任鏈模式模板代碼分享

    這篇文章主要介紹了Java責(zé)任鏈模式模板代碼分享,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01
  • SpringMVC框架中使用Filter實現(xiàn)請求日志打印方式

    SpringMVC框架中使用Filter實現(xiàn)請求日志打印方式

    這篇文章主要介紹了SpringMVC框架中使用Filter實現(xiàn)請求日志打印方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Spring Boot產(chǎn)生環(huán)形注入的解決方案

    Spring Boot產(chǎn)生環(huán)形注入的解決方案

    這篇文章主要介紹了Spring Boot產(chǎn)生環(huán)形注入的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 基于Java編寫簡易的算式測試程序

    基于Java編寫簡易的算式測試程序

    本文將利用Java語言編寫一個簡易的算式測試程序,這個程序可以自動生成指定數(shù)量的加減乘三則運算題目,感興趣的小伙伴可以了解一下
    2022-05-05
  • 最新評論

    香港 | 偏关县| 清水河县| 岳阳县| 方城县| 平舆县| 大关县| 汶上县| 丘北县| 吴堡县| 宝坻区| 三都| 临洮县| 浪卡子县| 临桂县| 西乌珠穆沁旗| 大竹县| 永新县| 襄汾县| 禄劝| 达拉特旗| 敖汉旗| 惠来县| 江孜县| 广德县| 竹北市| 普定县| 阳山县| 格尔木市| 湟中县| 平阳县| 汶川县| 吉林省| 广汉市| 张家港市| 台北市| 嫩江县| 湘乡市| 盐山县| 石狮市| 临澧县|