首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java多線程深度解析:JUC互斥鎖ReentrantLock核心原理與實戰

     編輯:Java 相關知識

ReentrantLock 核心特性解析

ReentrantLock 是 Java 並發包(JUC)中最基礎也最重要的鎖實現,它是一個可重入的互斥鎖,又稱「獨占鎖」。這意味著同一時間點僅允許一個線程持有該鎖,但同一線程可多次重複獲取鎖而不會發生死鎖。

公平鎖 vs 非公平鎖

ReentrantLock 提供兩種模式:

  • 公平鎖:線程嚴格按照 FIFO 隊列順序獲取鎖,先來先得,避免線程飢餓。
  • 非公平鎖(預設):線程嘗試直接搶佔鎖,無論隊列順序,吞吐量較高但可能導致飢餓。

兩者底層皆基於 AQS(AbstractQueuedSynchronizer)的同步隊列實現,差別在於 tryAcquire 邏輯的判斷條件。

核心 API 速查表

方法說明
lock()獲取鎖,若被佔用則阻塞等待
lockInterruptibly()可響應中斷地獲取鎖
tryLock()嘗試非阻塞獲取鎖,立即返回結果
tryLock(timeout, unit)帶超時的鎖獲取
unlock()釋放鎖,必須在 finally 塊中調用
newCondition()創建關聯的 Condition 對象,實現精準線程通信
isFair()判斷是否為公平鎖
getHoldCount()當前線程重入次數

實戰演練:生產者-消費者模型

示例 1:基礎同步版本

使用 lock()/unlock() 保護共享倉庫的生產/消費操作,確保線程安全:

public void produce(int val) {
    lock.lock();
    try {
        size += val;
        System.out.printf("%s produce(%d) --> size=%d%n", 
            Thread.currentThread().getName(), val, size);
    } finally {
        lock.unlock();
    }
}

運行結果:最終庫存 50,符合預期。但存在兩個業務邏輯缺陷:庫存可能為負數、無容量上限。

示例 2:無鎖對比版

註釋掉鎖操作後,多線程並發導致數據競爭,最終庫存出現 -60 等錯誤結果,直觀展示互斥鎖的必要性。

示例 3:Condition 完善版

引入 Condition 實現「滿倉等待、空倉等待」機制,解決業務缺陷:

private Condition fullCondition = lock.newCondition();  // 生產者等待條件
private Condition emptyCondition = lock.newCondition(); // 消費者等待條件

public void produce(int val) {
    lock.lock();
    try {
        int left = val;
        while (left > 0) {
            while (size >= capacity) fullCondition.await(); // 倉滿等待
            int inc = Math.min(left, capacity - size);
            size += inc; left -= inc;
            emptyCondition.signal(); // 喚醒消費者
        }
    } finally { lock.unlock(); }
}

關鍵點:

  • 雙重 while 迴圈防止虛假喚醒
  • signal() 單點喚醒,配合精準條件變量
  • 鎖與 Condition 綁定,確保原子性檢查-等待-通知流程

最佳實踐總結

  1. 永遠在 finally 中釋放鎖,防止異常導致死鎖
  2. 優先使用 tryLock(timeout) 避免無限阻塞
  3. 公平鎖適用於對延遲敏感、需嚴格順序的場景
  4. 複雜協調邏輯請配合 Condition 使用,而非 Object.wait/notify

ReentrantLock 作為 JUC 基石,掌握其原理與用法是構建高性能並發系統的關鍵一步。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved