首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么在实现Runnable时使用Thread.currentThread().isInterrupted()而不是Thread.interrupted()?

为什么在实现Runnable时使用Thread.currentThread().isInterrupted()而不是Thread.interrupted()?
EN

Stack Overflow用户
提问于 2013-06-04 19:06:54
回答 4查看 8.2K关注 0票数 11

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

代码语言:javascript
运行
复制
public void run() {
  while(!Thread.currentThread().isInterrupted()) { ... }
}

与使用Thread.interrupted()有什么不同(除了在使用interrupted()时清除了interrupted标志)?

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

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-09-05 22:42:20

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

首先,必须确定检查中断状态(或处理InterruptedException)的代码是否被视为线程的“所有者”。如果是这样,在某些有限的情况下,可以适当地接受(或不抛出) InterruptedException以及中断状态,因为所有者正在实现线程的取消策略(Goetz,Java Concurrency in Practice,p.143)。

但在绝大多数情况下,包括Runnable,有问题的代码不是线程所有者,并且不能吞噬取消状态。在这种情况下,您有两个选择:

  • 使线程中断状态保持清除状态,但抛出InterruptedException。(这就是Thread.sleep() does.)
  • Preserve Thread.sleep()中断状态。

Runnable的情况下,您不能引发检查异常,因为run()没有声明这样做。(反过来,我推测它是这样设计的,因为通常不会有人捕捉到它。)所以你唯一的选择就是保留取消状态。

考虑到上面的解释,让我回到你直接的问题上。首先,如果你想查看取消状态并保存它,它更容易编写

代码语言:javascript
运行
复制
if (Thread.currentThread().isInterrupted()) doSomething;

代码语言:javascript
运行
复制
if (Thread.interrupted()) {
    Thread.currentThread().interrupt();
    doSomething;
}

此外,与您最初的问题一样,如果在while循环中使用Thread.interrupted()作为条件,那么在循环中断后,您将不知道它是否因为Thread.interrupted()返回true或其他条件更改或运行了break语句而终止。因此,在这种情况下,使用Thread.currentThread().isInterrupted()实际上是您唯一的选择。(当然,您也可以对循环进行编码,使其退出的唯一原因是线程被中断,但这样做会使代码变得脆弱,因为在循环之后,您必须重新中断线程,并且如果后来有人出于其他原因更改了代码,使其也中断了循环,那么您就会在线程最初没有中断的时候中断它。)

对于你的第二个问题,正如其他人所说的那样,永远不要使用Thread.currentThread().interrupted(),因为它具有误导性。由于interrupted()是一种静态方法,如果您使用-Xlint编译,在这种情况下,编译器会给出一个有用的警告

警告:静态静态方法应由类型名和线程限定,而不是由表达式限定

其他一些工具可能会执行类似的操作,例如Eclipse,它将显示:

线程类型的静态方法

()应以静态方式访问

票数 7
EN

Stack Overflow用户

发布于 2013-06-04 19:14:51

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

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

在纯功能术语中,它们的含义完全相同。

但是在可读性方面,

代码语言:javascript
运行
复制
    Thread.currentThread().interrupted()

让它看起来像是在调用一个实例方法...但你不是。因此,

代码语言:javascript
运行
复制
    Thread.interrupted()

是更好的。当然也不要这样做:

代码语言:javascript
运行
复制
    Thread someThread = ...
    someThread.interrupted()

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

票数 6
EN

Stack Overflow用户

发布于 2013-06-04 19:10:24

区别是非常微妙的,通常并不重要。显然,您可以根据自己的意愿设置或清除中断标志。甚至没有一个标准的实践说“使用一个,而不是使用另一个”。

主要的一点是要知道你对中断标志做了什么:让它处于一种你不是特别想要的状态,这肯定不会只是一个细微的差别。

切勿使用Thread.currentThread().interrupted()。这只会产生误导,特别是如果你有someOtherThread.interrupted()的话。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16916238

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档