1

私はのコードを見ていましたArrayBlockingQueue.put(E)notFull.signalキャッチブロックでの呼び出しが本当に必要ですか?その信号は消費者によって呼び出されるべきではありませんか?

public void put(E e) throws InterruptedException {
    if (e == null) throw new NullPointerException();
    final E[] items = this.items;
    final ReentrantLock lock = this.lock;
    lock.lockInterruptibly();
    try {
        try {
            while (count == items.length)
                notFull.await();
        } catch (InterruptedException ie) {
            notFull.signal(); // propagate to non-interrupted thread
            throw ie;
        }
        insert(e);
    } finally {
        lock.unlock();
    }
}
4

2 に答える 2

1

その呼び出しはまったく必要ありません。最新バージョンのJDK(1.7.0_17)には、そのキャッチブロックすらありません。

public void put(E e) throws InterruptedException {
    checkNotNull(e);
    final ReentrantLock lock = this.lock;
    lock.lockInterruptibly();
    try {
        while (count == items.length)
            notFull.await();
        insert(e);
    } finally {
        lock.unlock();
    }
}
于 2013-03-07T17:21:11.240 に答える
1

懸念は、条件が通知され、スレッドが中断された場合、await()シグナルを消費し、InterruptedExceptionをスローすることであるように思われます。ただし、javadocは、await()InterruptedExceptionをスローする場合、シグナルを消費してはならないことを明確に禁止しています。

同様の懸念はにも当てはまりますObject.wait()。1.4では、javadocはそれほど明確ではありません。1.5以降、javadocは

スロー:InterruptedException-現在のスレッドが通知を待機する前または待機中に別のスレッドが現在のスレッドに割り込んだ場合。

wait()これは、InterruptedExceptionをスローした場合、通知を消費してはならないことを意味しているようです。

于 2013-03-07T19:45:16.087 に答える