在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并发实践,p。 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
或其他一些条件改变或a break
声明跑了。所以在那种情况下使用 Thread.currentThread().isInterrupted()
真的是你的 只要 选项。 (当然你也可以编写循环代码 只要 它会退出的原因是线程被中断了,但是你的代码会变得脆弱,因为在循环之后你必须重新中断线程,如果其他人后来出现并改变了代码,那么也会突破某些循环其他原因,当你没有最初中断线程时,你就会打断它。)
对于你的第二个问题,正如其他人所说, 决不 使用 Thread.currentThread().interrupted()
因为它有误导性。以来 interrupted()
是一个静态方法,在这种情况下,编译器会在您编译时为您提供有用的警告 -Xlint
:
警告:[静态]静态方法应该通过类型名称Thread来限定,而不是通过表达式来限定
其他一些工具也可能类似,例如Eclipse,它将显示:
应该以静态方式访问Thread类型的static()静态方法
只是回答你问题的最后部分......
我也见过 Thread.currentThread().interrupted()
。这是使用它的正确方法,或者是 Thread.interrupted()
足够?
在纯函数术语中,它们的含义完全相同。
但就可读性而言,
Thread.currentThread().interrupted()
做到了 看 就像你正在调用一个实例方法......但你不是。因此,
Thread.interrupted()
更好。当然不要这样做:
Thread someThread = ...
someThread.interrupted()
它 好像 你会测试 someThread
, 但你是 其实 测试当前线程。非常误导!
差异非常微妙,通常无关紧要。你可以根据需要设置或清除中断的标志。甚至没有标准的做法说“使用一个而不使用另一个”。
重点是要知道你正在用中断的标志做什么:把它留在一个你没有特别想要的状态 不 只是微妙的区别。
决不 使用 Thread.currentThread().interrupted()
。这只会产生误导,特别是如果你有的话 someOtherThread.interrupted()
。
使用有什么不同 Thread.interrupted()
(除了使用时清除中断的标志 interrupted()
)?
不,但这是一个非常深刻的区别。如果你只是在你的例子中使用它,在一个单独的内部 while
循环在线程中 run
方法,这样的 run
当线程中断时,方法退出,然后没有区别,但在其他情况下可能会有。例如,设想嵌套循环,每个循环检查中断状态(内部循环清除状态,然后外部检查它...)
至于之间的区别 Thread.currentThread().interrupted()
与 Thread.interrupted()
,没有功能差异,但后者更短,所以使用它。