8

我对 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

4 回答 4

18

在您的情况下,只需调用就足够了,!isInterrupted()因为您是从课程中扩展而来的Thread。通常你不会从Thread- 这就是你打电话的原因Thread.currentThread()

于 2012-07-27T07:05:43.373 回答
4

从 Java 5 开始,直接使用线程并不是一个好主意。您应该使用 Executor 框架并根据您的要求选择执行策略。实例isInterrupted()方法测试该线程是否被中断。线程的中断状态不受此方法的影响。innerisInterrupted()其实是一个native方法。

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

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

于 2012-07-27T07:44:27.500 回答
2

很清楚:它有效地将cancel调用定向到this.interrupt; 即应用该cancel方法的 Thread 实例。

至于该run方法,您陈述的所有内容都是在假设该run方法被实际调用并且仅由class A. 虽然这可能是一个安全的假设,但它普遍正确吗?现在,如果您要问我一个有意义的例子,说明如何/何时可能违反该假设,不确定我能否在深夜把它从帽子里拿出来:-)

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

于 2012-07-27T07:15:55.697 回答
1

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

于 2012-07-27T07:06:30.027 回答