Condition


Ojbect:
           waitotifyotifyAll
Condition: 
           await\signal\signalAll
 
ConditionインタフェースAPIで2つのconditionを使用する必要はありますか?
 
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();
        }
    }
}

以前にObjectを使用していたwait/notifyよりも、プログラムを書くとより明確になる必要があります.1つのConditionは1つの条件を表し、この条件の中にチェーンテーブルが1つあると、2つの条件に2つの待機チェーンテーブルがあります.待ち行列で起動されてから続行し、同時に2つの条件で制御される場合は、それぞれ2つの起動される必要があります.このように書くメリットは粒度が細かく、制御がより細かく、Objectのように粗粒度ではありません.
 
すみません、一つのコンディションで同じ効果が得られますか?もちろんいいです.構造的にはそんなにはっきりしていません.JDK 1はありません.5のコンカレントまではObject提供のwaitで生産者消費者キューを書くわけではありませんが、同じキューに複数の条件を関連付けて断言するのはsignalでは危険ですからsinalAllで
 
組み込みロックオブジェクトには1つの条件キューしかありません.明示的なロックでは、newConditionメソッドで複数の条件キューを作成できます.これにより、異なる条件断言が同じ条件キューに関連する問題を回避できます.
 
 
複数のスレッドが中にデータを格納し、中からデータを取得し、そのキュー(先に出てから出て)がキャッシュできる最大値はcapacityであり、複数のスレッド間で反発し、キャッシュキューに格納されている値がcapacityに達すると、書き込みスレッドをブロックし、読み取りスレッドを呼び出し、キャッシュキューに格納されている値が0の場合、読み取りスレッドをブロックし、書き込みスレッドを起動する
 
 
これが複数のConditionの強みです.キャッシュキューにすでにいっぱいあると仮定すると、ブロックされているのは書き込みスレッドに違いありません.起動されたのは読み取りスレッドに違いありません.逆に、ブロックされているのは読み取りスレッドに違いありません.起動されたのは書き込みスレッドに違いありません.では、1つのConditionだけでどのような効果があると仮定しますか.キャッシュキューにはすでにいっぱいです.このロックは起動したのがリードスレッドなのか、それともスレッドを書いたのか分からない.もし起動したのがリードスレッドであれば、みんな大喜びしている.もし起動したのがライトスレッドであれば、スレッドは起動されたばかりで、またブロックされている.この時、また起動して、このように多くの時間を浪費している.
 
ArrayBlockingQueueでもこの技術が用いられている.
Condition条件変数、スレッド通信がより効率的な方法