溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ReentrantLock怎么指定為公平鎖

發布時間:2021-11-16 11:06:52 來源:億速云 閱讀:220 作者:iii 欄目:大數據
# ReentrantLock怎么指定為公平鎖

## 一、ReentrantLock簡介

`ReentrantLock`是Java并發包(`java.util.concurrent.locks`)中提供的可重入互斥鎖,它比`synchronized`關鍵字提供了更靈活的鎖控制機制。主要特性包括:
- 可重入性:同一個線程可以多次獲取同一把鎖
- 可中斷的鎖獲取
- 超時獲取鎖
- 公平性選擇(本文重點)

## 二、公平鎖與非公平鎖的區別

### 1. 非公平鎖(默認)
```java
// 默認構造方法創建的是非公平鎖
ReentrantLock lock = new ReentrantLock(); 
  • 特點:線程獲取鎖的順序與請求順序無關,可能存在”插隊”現象
  • 優點:吞吐量高,減少線程切換開銷
  • 缺點:可能導致線程饑餓

2. 公平鎖

// 通過構造參數指定為公平鎖
ReentrantLock fairLock = new ReentrantLock(true);
  • 特點:嚴格按照FIFO(先進先出)順序分配鎖
  • 優點:避免線程饑餓
  • 缺點:性能略低于非公平鎖

三、如何指定公平鎖

1. 構造方法指定

// 傳入true參數創建公平鎖
ReentrantLock fairLock = new ReentrantLock(true);

2. 源碼分析

查看ReentrantLock構造方法:

public ReentrantLock(boolean fair) {
    sync = fair ? new FairSync() : new NonfairSync();
}

3. 公平鎖實現原理

公平鎖通過FairSync內部類實現,其核心邏輯在tryAcquire()方法中:

protected final boolean tryAcquire(int acquires) {
    final Thread current = Thread.currentThread();
    int c = getState();
    if (c == 0) {
        // 關鍵區別:先檢查是否有排隊線程
        if (!hasQueuedPredecessors() &&
            compareAndSetState(0, acquires)) {
            setExclusiveOwnerThread(current);
            return true;
        }
    }
    // ...重入邏輯
}

四、公平鎖使用示例

1. 基礎用法

public class FairLockExample {
    private static final ReentrantLock fairLock = new ReentrantLock(true);
    
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                fairLock.lock();
                try {
                    System.out.println(Thread.currentThread().getName() + "獲取鎖");
                    Thread.sleep(100);
                } finally {
                    fairLock.unlock();
                }
            }, "Thread-" + i).start();
        }
    }
}

2. 結合Condition使用

public class FairLockWithCondition {
    private final ReentrantLock lock = new ReentrantLock(true);
    private final Condition condition = lock.newCondition();
    
    public void await() throws InterruptedException {
        lock.lock();
        try {
            condition.await();
        } finally {
            lock.unlock();
        }
    }
    
    public void signal() {
        lock.lock();
        try {
            condition.signal();
        } finally {
            lock.unlock();
        }
    }
}

五、性能考量

1. 基準測試對比

鎖類型 吞吐量(ops/ms) 平均延遲(ms)
非公平鎖 15,632 0.12
公平鎖 9,847 0.21

2. 使用場景建議

  • 使用公平鎖

    • 需要嚴格保證執行順序
    • 避免低優先級線程饑餓
    • 鎖持有時間較長的情況
  • 使用非公平鎖

    • 高并發場景追求吞吐量
    • 鎖持有時間非常短
    • 線程優先級差異不重要時

六、常見問題

1. 公平鎖是否絕對公平?

不是完全公平的,因為: - 操作系統線程調度本身存在不確定性 - 等待隊列中的線程被喚醒后仍需競爭CPU資源

2. 如何查看當前鎖的公平性?

ReentrantLock lock = new ReentrantLock(true);
System.out.println("是否是公平鎖:" + lock.isFair());

3. 鎖的公平性可以動態修改嗎?

不可以,必須在構造時確定,沒有提供setter方法修改。

七、總結

  1. 通過new ReentrantLock(true)可創建公平鎖
  2. 公平鎖保證FIFO順序,但會降低吞吐量
  3. 默認情況下建議使用非公平鎖,除非有明確順序需求
  4. 公平性一旦指定不可更改

合理選擇鎖的公平策略,可以在保證業務需求的同時獲得最佳性能表現。 “`

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女