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