1

我正在查看ArrayBlockingQueue.put(E). 我们真的需要notFull.signal在 catch 块中调用 to 吗?消费者不应该调用那个信号吗?

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) 甚至没有那个 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();
    }
}
于 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 回答