为什么使用Thread.currentThread()。isInterrupted()而不是isInterrupted()?

时间:2012-07-27 07:03:28

标签: java multithreading concurrency

我对Thread子类的取消策略的实现有疑问。通常的做法是这样做:

class A extends Thread {

  [...]

  public final void run() {
     try {
        while(!Thread.currentThread().isInterrupted()) {
           [...]
        }
     } catch (InterruptedException consumed) {
     }
  }

  public final void cancel() {
     interrupt();
  }    
}

我遇到的问题是关于Thread.currentThread()...为什么通常的做法是使用currentThread()来检查中断标志而不是在cancel()方法中设置它?仅仅调用A的isInterrupted()方法就不够了:

while (!isInterrupted()) {
   [...]
}

我无法在Thread JavaDoc,Brian Goetz关于并发Java或stackoverflow的优秀书籍中找到答案。

提前感谢您的见解!

干杯, 乔治

4 个答案:

答案 0 :(得分:16)

在您的情况下,只需拨打!isInterrupted()即可,因为您正在从Thread课程延伸。通常情况下,您不会从Thread延伸 - 这就是您致电Thread.currentThread()的原因。

答案 1 :(得分:4)

从Java 5开始,它是not a good idea to work with Threads directly。您应该使用Executor框架并根据您的要求选择执行策略。实例isInterrupted()方法测试此线程是否已被中断。线程的中断状态不受此方法的影响。内部isInterrupted()实际上是本机方法。

906     public boolean isInterrupted() {
907         return isInterrupted(false);
908     }

在使用执行程序框架时,您不知道哪个线程实例当前正在执行您的代码,因此约定是使用Thread.currentThread.isInterrupted()

答案 2 :(得分:2)

cancel很清楚:它有效地将呼叫指向this.interrupt;即应用cancel方法的Thread实例。

对于run方法,您声明的所有内容都假设run方法实际上已被调用,并且仅由class A的(预期)实例调用。虽然这可能是一个安全的假设,但它是否普遍适用?现在,如果你要问我一个有意义的例子,说明这个假设可能会被违反的时间/时间,那么不确定我可以在晚上把这个从我的帽子中拉出来: - )

考虑run以外的方法。如果它是class A上的一个方法,它应该假设它被/在同一个线程上调用吗?也许这是另一个班级的方法。因此,这似乎是消除潜在错误的最佳实践:您的代码变得可以复制/粘贴[@Thomas也提供了这种洞察力]

答案 3 :(得分:1)

它应该是相同的,如果代码是在当前运行的线程中。 也许作者担心,有人会在其他线程中执行run方法,也许他们希望它看起来像其他地方一样。 或者他们复制粘贴它,并没有想到。