Java併發程式設計(十)Condition介面
阿新 • • 發佈:2018-12-04
一、Condition介面簡介
java.util.concurrent.locks.Condition是java併發包中的一個介面,是為配合Lock提供的執行緒等待/通知功能。我們知道Object的監視器方法wait()和notify()配合sychronized關鍵字一樣可以實現等待/通知機制,Condition的優勢在於它可以為多個執行緒間建立不同的Condition,控制粒度更細。如阻塞佇列同時有讀寫執行緒,該喚醒讀執行緒還是寫執行緒,notify方法無法直接指定,而Condition可以做到。
Conditon的所有方法:
public interface Condition { /** * 執行緒進入等待狀態,可被中斷 * @throws InterruptedException */ void await() throws InterruptedException; /** * 執行緒進入等待狀態,不可被中斷 */ void awaitUninterruptibly(); /** * 執行緒進入等待狀態,直到被中斷、到達指定時間或喚醒 * @param nanosTimeout * @return * @throws InterruptedException */ long awaitNanos(long nanosTimeout) throws InterruptedException; /** * 執行緒進入等待狀態,直到被中斷、到達指定時間或喚醒 * @param time * @param unit * @return * @throws InterruptedException */ boolean await(long time, TimeUnit unit) throws InterruptedException; /** * 執行緒進入等待狀態,直到被中斷、到達指定時間或喚醒 * @param deadline * @return * @throws InterruptedException */ boolean awaitUntil(Date deadline) throws InterruptedException; /** * 喚醒一個等待執行緒 */ void signal(); /** * 喚醒所有等待執行緒 */ void signalAll(); }
二、Condition介面應用
典型應用就是LinkedBlockingQueue的實現,通過兩個Condition分別控制讀寫執行緒的等待與通知,這裡特別強調下,呼叫await方法和signal方法之前,該執行緒必須先獲得鎖,原始碼如下:
public class LinkedBlockingQueue { private final ReentrantLock takeLock = new ReentrantLock(); private final Condition notEmpty = takeLock.newCondition(); private final ReentrantLock putLock = new ReentrantLock(); private final Condition notFull = putLock.newCondition(); public void put(E e) throws InterruptedException { // ... final AtomicInteger count = this.count; final ReentrantLock putLock = this.putLock; // 必須先獲得鎖才能呼叫condition方法 putLock.lockInterruptibly(); try { // 佇列滿時,通過notFull這個Conditon一直等待 while (count.get() == capacity) { notFull.await(); } // ... } finally { putLock.unlock(); } // ... } public E take() throws InterruptedException { // ... final AtomicInteger count = this.count; final ReentrantLock takeLock = this.takeLock; // 必須先獲得鎖才能呼叫condition方法 takeLock.lockInterruptibly(); try { // 佇列空時,通過notEmpty這個condition一直等待 while (count.get() == 0) { notEmpty.await(); } // ... } finally { takeLock.unlock(); } // ... } }
參考資料:
https://www.cnblogs.com/jalja/p/5895051.html