捕获InterruptedException后,为什么ArrayBlockingQueue发出'not full'信号?

时间:2014-02-11 02:02:15

标签: java multithreading java-6

ArrayBlockingQueue中,在put方法中,为什么在捕获notFull.signal()后会调用InterruptedException?当线程将要终止时,为什么它会发送一个“不完整”的线程。信号φ

来自source

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

1 个答案:

答案 0 :(得分:1)

想象一下以下场景:

  • 线程1和4正在等待notFull,队列已满,锁被释放。
  • 线程2持有锁,即将从队列中删除元素。
  • 线程3中断线程1。

现在想象下面的交错:

+-+--+--------+-----------+------- TIME +---+------------+---------------------->
| |  |        |           |             |   |            |
+---------+   +------------------+      +----------+     |
| Thread2 |   |      Thread2     |      | Thread2  |     |
|  lock() |   | notFull.signal() |      | unlock() |     |
+---------+   +------------------+      +----------+     |
  |  |                    |                 |            |
  +---------------------+ |                 |            |
  |       Thread3       | |                 |            |
  | Thread1.interrupt() | |                 |            |
  +---------------------+ |                 |            |
     |                    |                 |            |
     +---------------+    +-------------+   +---------+  +----------------------+
     |   Thread1     |    |   Thread1   |   | Thread1 |  |       Thread1        |
     | interrupted() |    | signalled() |   |  lock() |  | InterruptedException |
     +---------------+    +-------------+   +---------+  +----------------------+

如果InterruptedException未被捕获,而线程1只是为了解锁并放弃等待,该怎么办?线程4会发生什么,他还在等待notFull上的信号?信号已经由线程2发送,但恰好发生了接收线程,线程1被中断,信号被浪费

简而言之:如果线程在被中断时收到信号,它会将信号传递给另一个线程,这样它就不会丢失。这可以防止线程无限期地等待已经发生的事情。