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(); } } }
Condition
將 Object
監視器方法(wait
、notify
和 notifyAll
)分解成大相徑庭的對象,以便經過將這些對象與任意 Lock
實現組合使用,爲每一個對象提供多個等待 set(wait-set)。其中,Lock
替代了 synchronized
方法和語句的使用,Condition
替代了 Object 監視器方法的使用。java
條件(也稱爲條件隊列 或條件變量)爲線程提供了一個含義,以便在某個狀態條件如今可能爲 true 的另外一個線程通知它以前,一直掛起該線程(即讓其「等待」)。由於訪問此共享狀態信息發生在不一樣的線程中,因此它必須受保護,所以要將某種形式的鎖與該條件相關聯。等待提供一個條件的主要屬性是:以原子方式 釋放相關的鎖,並掛起當前線程,就像 Object.wait
作的那樣。線程
Condition
實例實質上被綁定到一個鎖上。要爲特定 Lock
實例得到 Condition
實例,請使用其 newCondition()
方法。code
做爲一個示例,假定有一個綁定的緩衝區,它支持 put
和 take
方法。若是試圖在空的緩衝區上執行 take
操做,則在某一個項變得可用以前,線程將一直阻塞;若是試圖在滿的緩衝區上執行 put
操做,則在有空間變得可用以前,線程將一直阻塞。咱們喜歡在單獨的等待 set 中保存 put
線程和 take
線程,這樣就能夠在緩衝區中的項或空間變得可用時利用最佳規劃,一次只通知一個線程。能夠使用兩個 Condition
實例來作到這一點。對象