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

Java使用重入鎖實現(xiàn)線程同步的示例代碼

 更新時間:2025年07月07日 09:28:36   作者:Katie。  
在多線程環(huán)境中,為保證對共享資源的安全訪問,常用的同步手段是 synchronized 關鍵字,但 synchronized 存在局限,本項目旨在通過示例演示如何使用 ReentrantLock 實現(xiàn)線程同步,替代 synchronized,并展示其高級功能,需要的朋友可以參考下

一、項目背景詳細介紹

在多線程環(huán)境中,為保證對共享資源的安全訪問,常用的同步手段是 synchronized 關鍵字。但 synchronized 存在以下局限:

  • 靈活性較低:不能嘗試超時獲取鎖,也無法中斷獲取鎖的線程;
  • 可見性:無法查看當前鎖是否被占用或等待隊列情況;
  • 公平性控制:無法直接控制鎖的公平或非公平策略。

Java 5 引入了更強大的 java.util.concurrent.locks 包,其中的 ReentrantLock(可重入鎖)在功能和性能上均優(yōu)于內(nèi)置鎖。它提供:

  • 嘗試獲取鎖tryLock()、tryLock(timeout, unit)
  • 可中斷的鎖獲取lockInterruptibly()
  • 公平鎖:通過構造函數(shù)選擇公平或非公平策略
  • 監(jiān)視器查詢getHoldCount()isLocked()、getQueueLength() 等方法

本項目旨在通過示例演示如何使用 ReentrantLock 實現(xiàn)線程同步,替代 synchronized,并展示其高級功能,如超時嘗試獲取鎖、公平策略和中斷響應。

二、項目需求詳細介紹

基本互斥訪問

  • 使用 ReentrantLock 替代 synchronized,在多個線程間安全地更新同一共享變量或數(shù)據(jù)結構;
  • 提供示例:多線程對同一計數(shù)器或共享列表進行增刪操作。

超時獲取鎖

  • 演示 tryLock(long timeout, TimeUnit unit) 用法,當鎖長時間被占用時拋出或走備用邏輯;

可中斷鎖獲取

  • 演示 lockInterruptibly(),在等待鎖期間響應中斷,避免因鎖阻塞導致的無法取消;

公平鎖與非公平鎖

  • 對比默認(非公平)鎖和通過 new ReentrantLock(true) 創(chuàng)建的公平鎖在高并發(fā)場景下的性能及線程調(diào)度差異;

鎖狀態(tài)監(jiān)控

  • 使用 getHoldCount()、getQueueLength()、hasQueuedThreads() 等方法,實時查詢鎖的占用與等待情況,打印日志監(jiān)控;

示例應用

  • 實現(xiàn)一個帶超時和中斷功能的共享資源訪問類 SharedResource;
  • 編寫多線程測試,模擬高并發(fā)下的鎖獲取、超時回退和中斷場景;

配置可控

  • 通過構造參數(shù)或配置文件動態(tài)切換公平性、超時閾值等;

文檔與示例

  • 在 README 中給出代碼調(diào)用示例及注意事項;
  • 對比 synchronizedReentrantLock 的使用差異。

三、相關技術詳細介紹

java.util.concurrent.locks.ReentrantLock

  • 基本方法lock()、unlock()lockInterruptibly()、tryLock()、tryLock(timeout, unit);
  • 構造參數(shù)new ReentrantLock()(非公平鎖)、new ReentrantLock(true)(公平鎖);

Condition 接口

  • 通過 lock.newCondition() 創(chuàng)建條件變量,替代 wait/notify,支持多條件隊列;
  • 方法:await()、signal()、signalAll()

鎖監(jiān)控與診斷

  • getHoldCount():返回當前線程重入次數(shù);
  • isLocked():鎖是否被任意線程占用;
  • hasQueuedThreads()、getQueueLength():等待鎖的線程信息;

中斷與超時

  • lockInterruptibly() 在鎖等待時可響應中斷;
  • tryLock(timeout, unit) 在指定時長內(nèi)等待,超時后返回 false

多線程測試

  • 使用 ExecutorService 啟動多個線程;
  • 使用 CountDownLatchCyclicBarrier 協(xié)調(diào)線程啟動同步測試;
  • 記錄鎖獲取次數(shù)與失敗次數(shù)進行統(tǒng)計。

四、實現(xiàn)思路詳細介紹

SharedResource 類設計

  • 內(nèi)部包含 private final ReentrantLock lock; 和可選的 Condition
  • 提供方法:
void safeIncrement() { lock.lock(); try { /* 更新共享計數(shù) */ } finally { lock.unlock(); } }
boolean trySafeIncrement(long timeout, TimeUnit unit) { if (lock.tryLock(timeout, unit)) { try { ... } finally { lock.unlock(); } } else { /* 超時邏輯 */ } }
void interruptibleAccess() throws InterruptedException { lock.lockInterruptibly(); try { ... } finally { lock.unlock(); } }
  • 若需要多個條件,可創(chuàng)建 Condition notEmptynotFull 并在方法中配合使用。

公平與非公平鎖對比

  • 在測試中構造兩種 SharedResource,公平鎖與非公平鎖,分別運行相同并發(fā)測試,比較吞吐量與線程饑餓情況。

監(jiān)控鎖狀態(tài)

  • 在方法中或監(jiān)控線程里定期調(diào)用 lock.getQueueLength()、lock.hasQueuedThreads() 并打印,觀察等待線程數(shù);
  • 結合 lock.getHoldCount() 了解重入深度。

多線程測試

  • 使用 ExecutorService 和多個工作線程不斷調(diào)用不同模式的方法;
  • 使用 CountDownLatch 保證開始同步,使用 AtomicInteger 統(tǒng)計成功與超時/中斷次數(shù);

文檔示例

  • 在 README 中說明各模式使用場景和注意事項,例如必須在 finally 塊中 unlock(),避免死鎖。
/*
 * =====================================================
 * File: SharedResource.java
 * 共享資源類,使用 ReentrantLock 實現(xiàn)多種同步策略
 * =====================================================
 */
package com.example.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class SharedResource {
    private int counter = 0;
    private final ReentrantLock lock;
    private final Condition notZero;

    /**
     * 構造函數(shù):可指定是否公平鎖
     */
    public SharedResource(boolean fair) {
        this.lock = new ReentrantLock(fair);
        this.notZero = lock.newCondition();
    }

    /**
     * 基本互斥:安全地遞增 counter
     */
    public void safeIncrement() {
        lock.lock();
        try {
            counter++;
            System.out.printf("%s incremented to %d%n",
                Thread.currentThread().getName(), counter);
            notZero.signalAll();
        } finally {
            lock.unlock();
        }
    }

    /**
     * 帶超時嘗試獲取鎖的遞增
     */
    public boolean trySafeIncrement(long timeout, TimeUnit unit) {
        boolean acquired = false;
        try {
            acquired = lock.tryLock(timeout, unit);
            if (acquired) {
                counter++;
                System.out.printf("%s timed increment to %d%n",
                    Thread.currentThread().getName(), counter);
                notZero.signalAll();
                return true;
            } else {
                System.out.printf("%s failed to acquire lock in %d %s%n",
                    Thread.currentThread().getName(), timeout, unit);
                return false;
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.out.printf("%s interrupted while waiting%n",
                Thread.currentThread().getName());
            return false;
        } finally {
            if (acquired) lock.unlock();
        }
    }

    /**
     * 可中斷地獲取鎖并等待 counter > 0 后消費
     */
    public int interruptibleConsume() throws InterruptedException {
        lock.lockInterruptibly();
        try {
            while (counter == 0) {
                System.out.printf("%s waiting for counter > 0%n",
                    Thread.currentThread().getName());
                notZero.await();
            }
            counter--;
            System.out.printf("%s consumed to %d%n",
                Thread.currentThread().getName(), counter);
            return counter;
        } finally {
            lock.unlock();
        }
    }

    /**
     * 監(jiān)控方法:打印當前鎖狀態(tài)
     */
    public void printLockStatus() {
        System.out.printf("Lock held by thread: %s, holdCount=%d, queuedThreads=%d%n",
            lock.isLocked() && lock.isHeldByCurrentThread()
                ? Thread.currentThread().getName()
                : "other",
            lock.getHoldCount(),
            lock.getQueueLength());
    }
}


/*
 * =====================================================
 * File: LockDemo.java
 * 演示:多線程調(diào)用 SharedResource 不同方法
 * =====================================================
 */
package com.example.lock;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class LockDemo {
    public static void main(String[] args) throws InterruptedException {
        SharedResource fairResource = new SharedResource(true);
        SharedResource unfairResource = new SharedResource(false);

        ExecutorService exec = Executors.newFixedThreadPool(6);
        CountDownLatch startLatch = new CountDownLatch(1);
        AtomicInteger successCount = new AtomicInteger(0);
        AtomicInteger failCount = new AtomicInteger(0);

        // 創(chuàng)建 2 個常規(guī)增量任務
        for (int i = 0; i < 2; i++) {
            exec.submit(() -> {
                await(startLatch);
                fairResource.safeIncrement();
            });
        }

        // 創(chuàng)建 2 個帶超時嘗試鎖任務
        for (int i = 0; i < 2; i++) {
            exec.submit(() -> {
                await(startLatch);
                if (fairResource.trySafeIncrement(500, TimeUnit.MILLISECONDS)) {
                    successCount.incrementAndGet();
                } else {
                    failCount.incrementAndGet();
                }
            });
        }

        // 創(chuàng)建 2 個可中斷消費任務
        for (int i = 0; i < 2; i++) {
            exec.submit(() -> {
                await(startLatch);
                try {
                    unfairResource.interruptibleConsume();
                } catch (InterruptedException e) {
                    System.out.printf("%s interrupted%n",
                        Thread.currentThread().getName());
                }
            });
        }

        // 啟動所有任務
        startLatch.countDown();

        // 等待一段時間后中斷消費任務
        Thread.sleep(1000);
        exec.shutdownNow();
        exec.awaitTermination(5, TimeUnit.SECONDS);

        System.out.printf("TryLock successes: %d, failures: %d%n",
            successCount.get(), failCount.get());
    }

    private static void await(CountDownLatch latch) {
        try {
            latch.await();
        } catch (InterruptedException ignored) {}
    }
}

代碼詳細解讀

SharedResource

  • safeIncrement():使用 lock.lock()unlock() 實現(xiàn)基本互斥,并在 notZero 條件上喚醒等待的消費者。
  • trySafeIncrement(timeout, unit):使用 tryLock(timeout, unit) 帶超時嘗試獲取鎖,超時后返回失敗邏輯。
  • interruptibleConsume():使用 lock.lockInterruptibly(),在等待中可響應中斷,配合 notZero.await() 等待條件。
  • printLockStatus():演示查詢鎖狀態(tài)的方法,包括持有計數(shù)和等待隊列長度。

LockDemo

使用 ExecutorService 啟動 6 個線程:

  • 2 個調(diào)用 safeIncrement()
  • 2 個調(diào)用 trySafeIncrement(500ms),統(tǒng)計成功與失敗次數(shù);
  • 2 個調(diào)用 interruptibleConsume(),并在主線程中斷它們,演示可中斷鎖獲??;
  • 使用 CountDownLatch 保證所有線程同時開始。
  • 程序運行 1 秒后調(diào)用 shutdownNow() 中斷消費任務,并打印 tryLock 的統(tǒng)計結果。

項目詳細總結

本示例通過 ReentrantLock 展示了:

  • 基本互斥:與 synchronized 類似,但可以更靈活地控制鎖釋放時機。
  • 超時獲取鎖tryLock(timeout, unit) 避免長時間阻塞,方便實現(xiàn)備用邏輯。
  • 可中斷鎖lockInterruptibly() 在等待鎖時響應中斷,提高了取消能力。
  • 公平與非公平:可通過構造函數(shù)選擇公平策略,避免線程饑餓。
  • 鎖監(jiān)控getHoldCount()getQueueLength() 等方法便于在運行時診斷鎖狀態(tài)。

項目常見問題及解答

為何要在 finallyunlock()?
避免在執(zhí)行過程中拋出異常導致鎖未釋放,進而引發(fā)死鎖。

tryLock 獲不到鎖后還能重試嗎?
可以在代碼中判斷失敗后循環(huán)調(diào)用,或結合退避機制重試。

公平鎖性能更差嗎?
是的,公平鎖會增加上下文切換成本,一般在需要嚴格順序時使用,否則推薦默認非公平鎖。

lockInterruptibly 如何正確處理中斷?
調(diào)用方法需聲明 throws InterruptedException,在捕獲后可執(zhí)行清理邏輯或直接結束任務。

如何監(jiān)控生產(chǎn)環(huán)境中的鎖競爭?
利用 lock.getQueueLength() 和日志定期采集,或結合 APM 工具監(jiān)控線程等待情況。

擴展方向與性能優(yōu)化

Condition 多隊列
使用多個 Condition 實現(xiàn)更精細的等待/喚醒控制,例如生產(chǎn)者—消費者的 notFull / notEmpty。

鎖分段
對大數(shù)據(jù)結構進行分段加鎖(類似 ConcurrentHashMap),降低鎖粒度提升并發(fā)度。

公平性調(diào)優(yōu)
在高并發(fā)場景下考慮非公平鎖與超時重試結合,避免嚴格公平帶來的吞吐下降。

鎖剝離
當只有讀操作時,可使用 ReadWriteLock 切換到無阻塞讀鎖,提高并發(fā)讀性能。

可視化診斷
集成到監(jiān)控平臺或定制 Web 界面,實時展示鎖爭用、隊列長度和線程等待圖。

以上就是Java使用重入鎖實現(xiàn)線程同步的示例代碼的詳細內(nèi)容,更多關于Java重入鎖線程同步的資料請關注腳本之家其它相關文章!

相關文章

  • 如何在Java中調(diào)用python文件執(zhí)行詳解

    如何在Java中調(diào)用python文件執(zhí)行詳解

    豐富的第三方庫使得python非常適合用于進行數(shù)據(jù)分析,最近在項目中就涉及到java調(diào)用python實現(xiàn)的算法,下面這篇文章主要給大家介紹了關于如何在Java中調(diào)用python文件執(zhí)行的相關資料,需要的朋友可以參考下
    2022-05-05
  • SpringBoot中使用Knife4j生成接口文檔的示例詳解

    SpringBoot中使用Knife4j生成接口文檔的示例詳解

    Knife4j 是一個基于 Swagger 的增強 UI 實現(xiàn),主要用于為 Spring Boot 應用程序生成 API 接口文檔,本文將詳細介紹如何在 Spring Boot 中集成 Knife4j,并通過不同注解來生成清晰的接口文檔,需要的可以參考一下
    2025-06-06
  • Java動態(tài)線程池插件dynamic-tp集成zookeeper

    Java動態(tài)線程池插件dynamic-tp集成zookeeper

    ZooKeeper是一個分布式的,開放源碼的分布式應用程序協(xié)調(diào)服務,是Google的Chubby一個開源的實現(xiàn),是Hadoop和Hbase的重要組件。它是一個為分布式應用提供一致性的軟件,提供的功能包括:配置維護、域名服務、分布式同步、組服務等
    2023-03-03
  • Java中computeIfAbsent的功能和語法小結

    Java中computeIfAbsent的功能和語法小結

    Java8的computeIfAbsent方法簡化了從Map中獲取值并處理默認值的過程,減少了手動null檢查的繁瑣,提高了代碼的簡潔性和可讀性,本文就來具體了解一下computeIfAbsent的使用,感興趣的可以了解一下
    2025-10-10
  • 深入理解Java設計模式之代理模式

    深入理解Java設計模式之代理模式

    這篇文章主要介紹了Java設計模式之代理模式的的相關資料,文中示例代碼非常詳細,供大家參考和學習,感興趣的朋友可以了解下
    2021-11-11
  • 10個Elasticsearch查詢的實用技巧分享

    10個Elasticsearch查詢的實用技巧分享

    Elasticsearch是一個非常流行的搜索引擎,已經(jīng)成為了許多企業(yè)的首選解決方案。本文將向大家介紹10個實用的Elasticsearch查詢技巧,并配上對應的代碼示例,希望對大家有所幫助
    2023-04-04
  • MyBatis中防止SQL注入講解

    MyBatis中防止SQL注入講解

    這篇文章主要介紹了MyBatis中防止SQL注入,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-12-12
  • Spring?Validation接口入?yún)⑿r炇纠a

    Spring?Validation接口入?yún)⑿r炇纠a

    Spring?Validation是一種用于實現(xiàn)數(shù)據(jù)校驗的框架,它提供了一系列的校驗器,針對不同的數(shù)據(jù)類型可以使用不同的校驗器進行校驗,下面這篇文章主要給大家介紹了關于Spring?Validation接口入?yún)⑿r灥南嚓P資料,需要的朋友可以參考下
    2023-06-06
  • java 實現(xiàn)web項目啟動加載properties屬性文件

    java 實現(xiàn)web項目啟動加載properties屬性文件

    這篇文章主要介紹了java 實現(xiàn)web項目啟動加載properties屬性文件,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • SpringBoot同時集成Mybatis和Mybatis-plus框架

    SpringBoot同時集成Mybatis和Mybatis-plus框架

    在實際開發(fā)中,項目里面一般都是Mybatis和Mybatis-Plus公用,但是公用有版本不兼容的問題,本文主要介紹了Spring Boot項目中同時集成Mybatis和Mybatis-plus,具有一檔的參考價值,感興趣的可以了解一下
    2024-12-12

最新評論

晴隆县| 临沧市| 鹿泉市| 晋城| 新野县| 宁都县| 福泉市| 宁城县| 长顺县| 隆林| 咸宁市| 嘉义县| 静海县| 浦县| 凌源市| 扎鲁特旗| 乐都县| 江西省| 邵武市| 宿松县| 灵川县| 宁津县| 综艺| 资源县| 吉安市| 灌云县| 寿阳县| 定西市| 循化| 新野县| 乌拉特后旗| 石泉县| 陇川县| 闽清县| 仁布县| 福安市| 图木舒克市| 五河县| 亳州市| 当雄县| 长岛县|