我对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的优秀书籍中找到答案。
提前感谢您的见解!
干杯, 乔治
答案 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方法,也许他们希望它看起来像其他地方一样。 或者他们复制粘贴它,并没有想到。