public void run() { while(!Thread.currentThread().isInterrupted()) { ... } }
使用Thread.interrupted()(除了使用interrupt())中断的标志被清除有什么区别吗?
我也看过Thread.currentThread().interrup().是正确的使用方法,还是Thread.interrupted()足够了?
解决方法
首先必须确定检查中断状态(或处理InterruptedException)的代码是否被认为是线程的“所有者”.如果是这样,在某些有限的情况下,因为所有者正在实现线程的取消策略(Goetz,Java Concurrency in Practice,第143页),所以可以适当地吞下(或不抛出)InterruptedException以及中断的状态.
但在绝大多数情况下,包括一个Runnable,有关的代码不是线程所有者,也不能吞下取消状态.在这种情况下,您有两个选择:
保持线程中断状态被清除,但抛出一个InterruptedException. (这是Thread.sleep()).
>保持中断状态.
在Runnable的情况下,您不能抛出检查的异常,因为没有声明run()这样做. (反过来,我的理论是这样设计的,因为通常没有人抓住它).所以你唯一的选择是保留取消状态.
鉴于上述解释,让我回到你的直接问题.首先,如果你想检查取消状态并保留它,它更容易写
if (Thread.currentThread().isInterrupted()) doSomething;
比
if (Thread.interrupted()) { Thread.currentThread().interrupt(); doSomething; }
此外,如同您的原始问题一样,如果您在一个while循环中使用Thread.interrupted()作为条件,则在循环中断之后,您不知道是否终止,因为Thread.interrupted()返回true或其他一些条件已更改或一个休息声明跑了所以在这种情况下,使用Thread.currentThread().isInterrupted()真的是你唯一的选择. (当然你也可以对循环进行编码,这样才能退出的唯一原因是线程被中断了,但是你的代码会很脆弱,因为循环后你必须重新中断线程,如果别人后来并且由于某些其他原因,将代码更改为循环,否则当原始中断时,您将中断线程.)
对于您的第二个问题,正如其他人所说,不要使用Thread.currentThread().interrup(),因为它是误导的.由于interrup()是一个静态方法,在这种情况下,如果使用-Xlint编译,编译器会给您一个有用的警告:
warning: [static] static method should be qualified by type name,Thread,instead of by an expression
一些其他工具可能会做类似的工作,如Eclipse,它将显示:
The static method interrupted() from the type Thread should be accessed in a static way