java - 为什么 ArrayBlockingQueue 在捕获 InterruptedException 后会发出 'not full' 信号?

标签 java multithreading java-6

ArrayBlockingQueue ,在 put 方法中,为什么在捕获 InterruptedException 后调用 notFull.signal() ?当线程要终止时,为什么会发出“未满”信号?

来自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 和 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 只是解锁并放弃等待怎么办?仍在等待 notFull 信号的线程 4 会发生什么情况?信号已经被线程 2 发送,但恰好接收线程线程 1 被中断,信号被浪费了。

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

关于java - 为什么 ArrayBlockingQueue 在捕获 InterruptedException 后会发出 'not full' 信号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21691638/

相关文章:

java - 在 Java 中实现 Graph,出现原始类型错误

java - Android - WebView向下滚动时刷新

multithreading - 当前线程中未找到 OpenGL 上下文

Java 线程和关闭 Hook

c++ - 线程管理和与 boost::thread 的并行性

java - 切换到 Java 8 时出现比较器问题

Java 小程序日志记录

java - 期待关闭,在第 1 行附近发现 'WHEN' 异常?如何在 HIbernate 中摆脱它

java - Java 5 和 6 中最有用或最有趣的新语言特性?

Java同步问题,线程间通信