在stackoverflow上,经常看到Thread.currentThread().isInterrupted()
的使用。当实现 Runnable
并在 while 循环中使用它时,如下所示:
public void run() {
while(!Thread.currentThread().isInterrupted()) { ... }
}
使用 Thread.interrupted()
有什么区别吗(除了使用 interrupted()
时清除了 interrupted
标志) ?
我还看到了 Thread.currentThread().interrupted()
。这是使用它的正确方法,还是 Thread.interrupted()
就足够了?
最佳答案
如您所说,不同之处在于,一种清除线程的中断状态,另一种不清除。既然您已经知道这一点,那么您真正要问的似乎是保持线程的中断状态是否重要。
首先必须确定检查中断状态(或处理 InterruptedException
)的代码是否被视为线程的“所有者”。如果是这样,在某些有限的情况下,吞下(或只是不抛出)InterruptedException
以及中断状态可能是合适的,因为所有者正在实现线程的取消策略(Goetz, Java 并发实践,第 143 页)。
但在绝大多数情况下,包括 Runnable
,有问题的代码不是线程所有者并且不得吞下取消状态。在这种情况下,您有两种选择:
- 清除线程中断状态但抛出
InterruptedException
。 (这就是Thread.sleep()
所做的。) - 保留中断状态。
在 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
编译,编译器会给您一个有用的警告:
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
关于java - 为什么在实现 Runnable 时使用 Thread.currentThread().isInterrupted() 而不是 Thread.interrupted()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16916238/