2009-07-14 89 views
3

当队列中没有任何内容和调用take()时会发生什么。 API表示该方法将等待,但这是否意味着CPU将在空闲/非空空闲时检查空队列,或者是否意味着该线程产生并将被中断唤醒?如果是前者的情况,我可能想要查看队列是否为空,以及是否调用thread.yield()来放弃处理器时间。我的问题是我真的需要调用yield还是为内部机制处理这个问题?java&线程:中断的异常和如何正确使用BlockingQueue的take()方法

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

+1

文章上InterruptedException的:戈茨:http://www.ibm.com/developerworks/java/library/j-jtp05236 .html Kabutz:http://www.javaspecialists.co。za/archive/Issue056.html – McDowell 2009-07-14 08:32:12

+0

我建议提交2个问题而不是2个问题。否则,它使投票体面的答案更复杂一点 – 2009-07-14 16:57:46

回答

4

wait()调用不旋转,它通常使用OS服务来等待事件/条件 - 这会将线程置于休眠状态,直到条件/事件再次发出信号。等待时不使用处理器时间。

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

+0

我怎么知道等待事件/条件会把线程睡觉?换句话说,api并没有说线程会进入睡眠状态并被唤醒,所以我怎么知道这个方法实际上会做什么? – jbu 2009-07-14 08:47:44

+0

您可以查看Sun提供的源代码。如果你正在使用另一个Java实现,我不知道。 – nos 2009-07-14 11:48:41

0

调用yield()被认为是一个坏习惯,因为它不能确保的好处 - 您可以调用它并且调度程序立即返回到您的线程,因为它是无操作的。使用定时等待(例如,等待(1000))。

中断的信号,你想从它的东西一个线程安全的方式 - 停止处理,醒来的东西作出反应,等

一般来说,这些事情都取决于你的具体方案。 Java具有一些关于并发性的优点,可以更适用于某种情况。

5

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

如果锁不可用, 当前线程 线程调度目的,将被禁用,位于 休眠状态,直到两件事情 一个情况:

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

锁获得支持。

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

Re。您的关于中断的问题,Java专家通讯在interrupt()上有一个very interesting article和捕获/处理InterruptedException

阅读文章,但本质上,如果你捕获异常,你reinterrupt:

try { 
     Thread.sleep(1000); 
     } catch (InterruptedException ex) { 
     Thread.currentThread().interrupt(); // very important 
     break; 
     } 
相关问题