我们在ArrayBlockingQueue.put(E)中是否需要Condition.signal

时间:2013-03-07 17:10:49

标签: java concurrency

我正在查看ArrayBlockingQueue.put(E)的代码。我们真的需要在catch块中调用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();
    }
}

2 个答案:

答案 0 :(得分:1)

我们根本不需要那个电话。最新版本的JDK(1.7.0_17)甚至没有那个catch块。

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();
    }
}

答案 1 :(得分:1)

关注似乎是,如果发出条件信号,并且线程被中断,await()消耗信号并抛出InterruptedException。但是,javadoc特别禁止 - 如果await()抛出InterruptedException,它就不会消耗信号。

类似的问题也适用于Object.wait()。在1.4中,javadoc不是很确定。从1.5开始,javadoc说

  

抛出:InterruptedException - 如果另一个线程在当前线程等待通知之前或当前线程中断当前线程。

这似乎暗示如果wait()抛出InterruptedException,它就不能使用通知。