3

当队列中没有任何内容并调用 take() 时,究竟会发生什么。API 说该方法将等待,但这是否意味着 CPU 会旋转检查是否为空/非空,直到有项目在队列中,或者是否意味着线程产生并会被中断唤醒?如果是前者,我可能想看看队列是否为空,以及是否调用 thread.yield() 以放弃处理器时间。我的问题是我真的需要调用 yield 还是一些内部机制为我处理?

其次,中断异常是什么意思?如果我理解正确,这意味着如果线程 A 正在执行此方法并且正在等待输入并且另一个线程 B 调用 threadA.interrupt() 那么线程 A 将捕获中断的异常并可能暂停执行,如果它很好的话。这是正确的思考方式吗?

4

3 回答 3

5

注意 BlockingQueue 是一个接口。所以接下来是依赖于实现的。如果您查看(比如说)LinkedBlockingQueue的源代码,take() 的源代码会在 RentrantLock 上调用 lockInterruptibly()。从文档中:

如果锁不可用,则当前线程将被禁用以用于线程调度目的并处于休眠状态,直到发生以下两种情况之一:

* The lock is acquired by the current thread; or
* Some other thread interrupts the current thread, and interruption of

支持锁获取。

我怀疑有一些wait()/notify()或类似的事情发生。它会旋转CPU吗?否(通过top或类似方式检查)

回覆。关于中断的问题,Java 专家时事通讯有一篇非常有趣的文章,关于interrupt()和捕获/处理InterruptedException.

阅读这篇文章,但本质上,如果你捕捉到异常,你就会重新中断:

  try {
        Thread.sleep(1000);
      } catch (InterruptedException ex) {
        Thread.currentThread().interrupt(); // very important
        break;
      }
于 2009-07-14T08:40:57.327 回答
4

wait() 调用不会自旋,它通常使用操作系统服务来等待事件/条件——这会使线程进入睡眠状态,直到再次发出条件/事件信号。等待时不使用处理器时间。

如果线程在 wait() 调用中阻塞,并且另一个线程在该阻塞线程上调用 interrupt(),通常会得到中断异常,就像你说的那样。

于 2009-07-14T07:52:50.870 回答
0

调用 yield() 被认为是一种不好的做法,因为它不能确保良好- 您可以调用它并且调度程序会立即返回到您的线程,因为它是无操作的。请改用定时等待(例如 wait(1000))。

中断是一种安全的方式来向线程发出您想要从中获得某些东西的信号——停止处理、唤醒并响应某些东西等。

一般来说,这些事情取决于你的具体情况。Java 有一些关于并发的不错的特性,可以更适用于某种情况。

于 2009-07-14T08:06:49.640 回答