Java 为什么将Thread.currentThread().isInterrupted()与try/catch一起使用
我发现这种结构在java思考的多线程章节中很流行:Java 为什么将Thread.currentThread().isInterrupted()与try/catch一起使用,java,multithreading,Java,Multithreading,我发现这种结构在java思考的多线程章节中很流行: 然而,我现在认为,当且仅当阻塞的wait()、sleep()或I/O抛出InterruptedExeption时,while循环才会退出,为什么不改为使用while(true)?或者仅仅因为Thread.currentThread().isInterrupted()是规范的?您也可以从外部使用Thread.interrupt()中断线程。所以说它基本上是一个内置布尔标志 在这种情况下,你是对的。您可以使用while(true),因为当发生中断异
然而,我现在认为,当且仅当阻塞的
wait()
、sleep()
或I/O
抛出InterruptedExeption
时,while循环才会退出,为什么不改为使用while(true)
?或者仅仅因为Thread.currentThread().isInterrupted()
是规范的?您也可以从外部使用Thread.interrupt()
中断线程。所以说它基本上是一个内置布尔标志
在这种情况下,你是对的。您可以使用
while(true)
,因为当发生中断异常时,它将中断循环。作者可能想用一种连贯的方式来解释它。可能有一章是关于如何停止一条无止境的线。这是一个人为的、相当糟糕的例子。你说得对,while(true)
是一个完美的替代品
sleep
和wait
已检查此标志。他们使用它来知道是否抛出异常
因此,本守则:
public void run(){
try{
while(!Thread.currentThread().isInterrupted()){
Thread.sleep(100);
}
}catch(InterruptedExeption e){
}
}
基本上表示这种逻辑(伪代码):
这显然有点复杂,毫无意义
更重要的是,
Thread.sleep
实际上调用了interrupted
,而不是isInterrupted
,这是一个微妙的不同,因为它实际上重置了标志,因此线程看起来是不间断的。显然是根据:
如果此线程在调用对象类的wait()、wait(long)或wait(long,int)方法时被阻塞,或者在调用此类的join()、join(long)、join(long,int)、sleep(long)或sleep(long,int)方法时被阻塞,则其中断状态将被清除,并将接收到InterruptedException
因此,
isInterrupted()
的返回值和InterruptedException
的含义不一定相同。请参阅API文档以了解更多其他条件。由于所有可运行操作都是睡眠,因此不需要对中断进行检查。但正如你从评论中可以看出的,这是一个更大的例程的模型。虽然sleep和wait抛出InterruptedException,但阻塞I/O调用(列在注释中)不会,不等待或睡眠的CPU密集型代码也不会
Bruce E在这里所做的是为您提供一个模板,用于处理抛出InterruptedException的情况(他使用它退出循环),以及处理不涉及睡眠或等待且不抛出InterruptedException的情况。它让读者知道他们有一个显式检查标志的选项,并演示了正确的方法(而不是使用中断方法来清除标志) 因此,事实上,如果线程正在调用
wait
或sleep
,那么这些方法无论如何都会重置该标志,使得在循环时从外部检查它几乎毫无意义。@Michael我同意。事实上,我不记得在我的代码中调用过isInterrupted()
。我的回答只是试图为书中的示例代码找到一些基本原理。如果您感兴趣,这里会涉及到这一点。是的,但是这个“模板”只对重复循环相当快的操作的runnable有用。在循环体中输入的任何慢代码都需要一段时间才能终止(在这种情况下,如果可能的话,可能代码应该定期检查标志)。任何不循环的内容都不能使用此模板。作为一个模板,它实际上是一个令人难以置信的利基。@michael:这只是一个起点。让人们知道isInterrupted方法存在是件好事,但这不是一个好的起点。仅仅因为它在一本书中并不意味着它是好的。还有更好的。
public void run(){
try{
while(!Thread.currentThread().isInterrupted()){
Thread.sleep(100);
}
}catch(InterruptedExeption e){
}
}
try {
while(!Thread.currentThread().isInterrupted())
{
/* Thread.sleep */
boolean keepSleeping = true;
while(keepSleeping)
{
if (Thread.currentThread().isInterrupted())
{
throw new InterruptedExeption();
}
actualSleep(/*a very small amount of time*/);
if (/* we've slept long enough*/)
{
keepSleeping = false;
}
}
/* End Thread.sleep */
}
}catch(InterruptedExeption e){
}