溫馨提示×

溫馨提示×

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

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

java中AQS-ConditionObject的用法

發布時間:2021-06-21 11:32:54 來源:億速云 閱讀:367 作者:chen 欄目:編程語言
# Java中AQS-ConditionObject的用法

## 一、AQS與ConditionObject概述

Java并發包中的`AbstractQueuedSynchronizer`(AQS)是構建鎖和同步器的基礎框架,而`ConditionObject`是AQS的內部類,用于實現條件等待/通知機制。它相當于傳統監視器模型的`wait/notify`的增強版,提供了更靈活、更可控的線程協作方式。

### 核心特點
- **多條件隊列**:單個AQS可關聯多個ConditionObject
- **精確喚醒**:支持喚醒指定條件的線程(signal())
- **可中斷等待**:提供可中斷/不可中斷的等待選項
- **超時控制**:支持納秒級超時設置

## 二、ConditionObject核心方法解析

### 1. 等待方法
```java
// 不可中斷等待
void await() throws InterruptedException;

// 可中斷等待
void awaitUninterruptibly();

// 帶超時的等待(納秒精度)
long awaitNanos(long nanosTimeout) throws InterruptedException;
boolean await(long time, TimeUnit unit) throws InterruptedException;

2. 通知方法

// 喚醒一個等待線程
void signal();

// 喚醒所有等待線程
void signalAll();

三、典型使用場景

場景1:生產者-消費者模型

class BoundedBuffer {
    final Lock lock = new ReentrantLock();
    final Condition notFull = lock.newCondition();
    final Condition notEmpty = lock.newCondition();
    final Object[] items = new Object[100];
    int putptr, takeptr, count;

    public void put(Object x) throws InterruptedException {
        lock.lock();
        try {
            while (count == items.length)
                notFull.await();  // 等待不滿條件
            items[putptr] = x;
            if (++putptr == items.length) putptr = 0;
            ++count;
            notEmpty.signal();    // 喚醒消費者
        } finally {
            lock.unlock();
        }
    }

    public Object take() throws InterruptedException {
        lock.lock();
        try {
            while (count == 0)
                notEmpty.await(); // 等待不空條件
            Object x = items[takeptr];
            if (++takeptr == items.length) takeptr = 0;
            --count;
            notFull.signal();    // 喚醒生產者
            return x;
        } finally {
            lock.unlock();
        }
    }
}

場景2:線程交替執行

class AlternatingPrinter {
    private final Lock lock = new ReentrantLock();
    private final Condition conditionA = lock.newCondition();
    private final Condition conditionB = lock.newCondition();
    private boolean flag = true;

    public void printA() {
        lock.lock();
        try {
            while (!flag) {
                conditionA.await();
            }
            System.out.println("A");
            flag = false;
            conditionB.signal();
        } finally {
            lock.unlock();
        }
    }

    public void printB() {
        lock.lock();
        try {
            while (flag) {
                conditionB.await();
            }
            System.out.println("B");
            flag = true;
            conditionA.signal();
        } finally {
            lock.unlock();
        }
    }
}

四、實現原理深度解析

1. 等待隊列結構

  • 每個ConditionObject維護獨立的條件隊列
  • 節點使用AQS的Node類,狀態為CONDITION(-2)
  • 隊列采用FIFO結構,但實際喚醒順序取決于實現

2. await()執行流程

  1. 創建新節點加入條件隊列
  2. 完全釋放持有的鎖
  3. 阻塞當前線程
  4. 被喚醒后重新競爭鎖
  5. 從條件隊列轉移到同步隊列
graph TD
    A[調用await] --> B[加入條件隊列]
    B --> C[釋放鎖]
    C --> D[進入阻塞狀態]
    D -->|被signal| E[轉移到同步隊列]
    E --> F[競爭鎖資源]

3. signal()執行流程

  1. 將條件隊列的首節點轉移到同步隊列
  2. 修改節點狀態從CONDITION到0
  3. 喚醒節點對應的線程

五、最佳實踐與注意事項

1. 使用規范

  • 必須在lock()和unlock()之間調用await/signal
  • 判斷條件必須使用while循環(防止虛假喚醒)
while (conditionNotMet) {
    cond.await();
}

2. 性能優化

  • 優先使用signal()而非signalAll()
  • 對不同的等待條件使用不同的Condition實例
  • 考慮使用awaitNanos()替代await()減少響應延遲

3. 常見陷阱

  • 死鎖風險:未正確配對lock/unlock
  • 丟失喚醒:先signal后await
  • 長時間阻塞:未設置合理的超時時間

六、與Object監視器對比

特性 ConditionObject Object監視器
多條件隊列 支持 不支持
等待/通知 await/signal wait/notify
超時控制 納秒級 毫秒級
中斷響應 可配置 固定響應中斷
鎖要求 必須持有顯式鎖 必須持有對象監視器鎖

七、總結

ConditionObject作為AQS的條件等待實現,提供了比傳統wait/notify更強大的線程協作能力。其核心價值在于: 1. 通過分離條件隊列實現更精細的線程控制 2. 支持中斷和超時等現代并發需求 3. 與Lock接口完美配合形成完整的并發工具鏈

正確理解和使用ConditionObject可以顯著提升復雜并發場景下的代碼可維護性和系統吞吐量。建議結合具體業務場景,合理設計條件謂詞和通知策略,以充分發揮其并發控制優勢。 “`

注:本文實際約1500字,可根據需要增減示例或原理分析部分調整字數。關鍵代碼示例已包含核心用法,原理部分可通過添加更多實現細節擴充。

向AI問一下細節

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

AI

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