11

在 stackoverflow 上,我经常看到Thread.currentThread().isInterrupted(). 在 while 循环中实现Runnable和使用它时,如下所示:

public void run() {
  while(!Thread.currentThread().isInterrupted()) { ... }
}

使用有什么区别Thread.interrupted()(除了interrupted使用时清除标志interrupted())?

我也见过Thread.currentThread().interrupted()。这是使用它的正确方法,还是Thread.interrupted()足够了?

4

4 回答 4

7

正如您所说,不同之处在于一个清除线程的中断状态而一个不清除。既然您已经知道这一点,那么您似乎真正要问的是保持线程的中断状态是否重要。

首先必须确定检查中断状态(或处理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() 应该以静态方式访问

于 2013-09-05T14:42:19.760 回答
6

只是回答你问题的最后一部分......

我也见过Thread.currentThread().interrupted()。这是使用它的正确方法,还是Thread.interrupted()足够了?

就纯粹的功能而言,它们的含义完全相同。

但就可读性而言,

    Thread.currentThread().interrupted()

使它看起来像你正在调用一个实例方法......但你不是。所以,

    Thread.interrupted()

更好。当然不要这样做:

    Thread someThread = ...
    someThread.interrupted()

看起来您正在测试someThread,但实际上您正在测试当前线程。非常误导!

于 2013-06-04T11:14:50.627 回答
3

差异非常微妙,通常无关紧要。您显然可以根据需要设置或清除中断标志。甚至没有一个标准的做法是说“使用一个,从不使用另一个”。

要点是要知道你在用中断标志做什么:让它处于你没有特别打算的状态绝对不会产生细微的差别。

永远不要使用Thread.currentThread().interrupted(). 这只会产生误导,特别是如果你有someOtherThread.interrupted().

于 2013-06-04T11:10:23.953 回答
0

使用有什么区别Thread.interrupted()(除了使用时清除中断标志interrupted())?

不,但这是一个非常深刻的区别。如果您仅在示例中使用它,在while线程方法的单个循环中使用它run,以便run在线程中断时退出该方法,那么没有区别,但在其他情况下可能有区别。例如,想象嵌套循环,每个循环都检查中断状态(内部循环在外部循环检查之前清除状态......)

至于Thread.currentThread().interrupted()vs.之间Thread.interrupted()的区别,没有功能上的区别,但后者更短,所以使用它。

于 2013-06-04T11:12:37.353 回答