正如你所说的那样,区别在于,它清除线程的中断状态,而不是线程中断状态.既然你已经知道了,似乎你真正在问的是保持线程中断状态是很重要的.
首先必须确定检查中断状态(或处理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