正如您所说,不同之处在于一个清除线程的中断状态而一个不清除。既然您已经知道这一点,那么您似乎真正要问的是保持线程的中断状态是否重要。
首先必须确定检查中断状态(或处理InterruptedException
)的代码是否被认为是线程的“所有者”。如果是这样,在某些有限的情况下,吞下(或只是不抛出)InterruptedException
以及中断状态可能是合适的,因为所有者正在实施线程的取消策略(Goetz,Java Concurrency in Practice,第 143 页)。
但在绝大多数情况下,包括 a Runnable
,有问题的代码不是线程所有者,不能吞下取消状态。在这种情况下,您有两种选择:
- 清除线程中断状态但抛出
InterruptedException
. (这就是这样Thread.sleep()
做的。)
- 保留中断状态。
在 a 的情况下Runnable
,您不能抛出已检查的异常,因为run()
没有声明这样做。(反过来,我认为它是这样设计的,因为通常没有人能抓住它。)所以你唯一的选择是保持取消状态。
鉴于上述解释,让我回到您的直接问题。首先,如果要查看取消状态并保存,写起来比较容易
if (Thread.currentThread().isInterrupted()) doSomething;
比
if (Thread.interrupted()) {
Thread.currentThread().interrupt();
doSomething;
}
此外,与您最初的问题一样,如果您在循环中用作Thread.interrupted()
条件while
,则在循环中断后,您将不知道它是否因Thread.interrupted()
返回true
或其他条件更改或break
语句运行而终止。因此,在这种情况下,使用Thread.currentThread().isInterrupted()
确实是您唯一的选择。(当然,您也可以编写循环代码,使其退出的唯一原因是线程被中断,但是您的代码会很脆弱,因为在循环之后您必须重新中断线程并且如果其他人后来出现并更改代码以出于其他原因也跳出循环,然后您将在线程最初未被中断时中断线程。)
对于您的第二个问题,正如其他人所说,永远不要使用Thread.currentThread().interrupted()
,因为它具有误导性。由于interrupted()
是静态方法,在这种情况下,如果您使用以下代码编译,编译器会给您一个有用的警告-Xlint
:
警告:[静态] 静态方法应由类型名称 Thread 限定,而不是由表达式限定
其他一些工具可能会做类似的事情,例如 Eclipse,它将显示:
Thread 类型的静态方法 interrupted() 应该以静态方式访问