这篇IBM developerWorks文章 状态:
“有一次,当你知道线程即将退出时,吞下一个中断是可以接受的。只有当调用可中断方法的类是a的一部分时,才会出现这种情况 Thread
不是 Runnable
[...]”。
我总是实施 Runnable
我的线程到现在为止。给...一个 Runnable
像这样的实现:
public class View() implements Runnable {
@Overload
public void run(){
Thread worker = new Thread(new Worker());
worker.start();
do{
try{
TimeUnit.SECONDS.sleep(3);
updateView();
}catch(InterruptedException e){
worker.interrupt();
// Thread.currentThread().interrupt();
return;
}
}while(true);
}
protected void updateView(){
// …
}
}
是否真的有必要打电话 Thread.currentThread().interrupt();
就在我之前 return;
声明?不 return;
已经执行一个干净的enaugh出口?叫它有什么好处?文章指出应该这样做,因为否则“[...]代码更高的代码将无法找到它[...]”。一个帖子的好处是什么? Thread.State.TERMINATED
在应用程序关闭时没有它的中断标志设置?你能给我一个例子吗? Runnable
出于明智的原因检查中断的旗帜?
顺便说一句,这是一个更好的代码设计扩展 Thread
而不是实施 Runnable
?
它会重置中断标志。这个 Java专家通讯 更详细地介绍了这个令人困惑的主题。
在我的例子中,在我捕获InterruptedException之后,我使用了
Thread.currentThread()。interrupt()立即中断了
线程再次。为什么这有必要?当抛出异常时,
中断标志被清除,所以如果你有嵌套循环,你会
在外循环中造成麻烦
因此,如果您知道您的代码不会被其他组件使用,那么您不需要重新中断。但是我真的不会做那个小小的优化。谁知道你的代码将来如何被使用/重用(甚至通过复制/粘贴),因此我会为每个中断重置标志。
这是一个返回它还不够的例子:
public void doSomething1() {
while (someCondition1()) {
synchronized {
try {
this.wait();
} catch (InterruptedException e) {
return; // Should be Thread.currentThread().interrupt();
}
}
}
}
public void doSomething2() {
while (someCondition2()) {
doSomething1();
}
}
当异常throw在下次执行doSomething1()时清除中断状态时,状态被清除,线程不会终止。
我更喜欢延伸 Thread
因为它可以让你更好地理解线程正在做什么,但它不一定是更好的代码设计。
正如布莱恩所说,它重置了中断标志,但这并没有多说。在你的情况下,它什么也不做 View
-Thread将继续运行。
在中断Thread时,标准过程是Thread应该停止运行。它不会自动执行此操作,您必须实现一种方法,以便在中断后停止它。
使用内置功能有两种选择:
- 将主循环放在try-block中
InterruptedException
。这样,当它被中断时,你将被抛出循环,方法将退出。
- 如果你必须保存状态,上面可能是坏的,因为它可能会破坏状态。作为替代方案,您可以设置interrupt-flag(如抛出时所说的那样。重新中断它中断线程
无论哪种方式,您都必须检查线程是否在您的while循环中被中断(使用 !Thread.currentThread().isInterrupted()
- while循环中的语句)或者它可能/不会退出。你没有完成第一个选项之一,也没有检查标志,所以你的 View
-thread将在被打断后继续运行。
是否真的有必要打电话 Thread.currentThread().interrupt();
就在我之前 return;
声明?
作为一个观点,我总是这样做。我们所有的复制粘贴代码和吞下中断都是一个严重的问题,我通常都是这样 总是 做到这一点,即使线程即将死亡。
不 return;
已经进行了足够干净的退出?
如果你确定它是之前的最后一次回归 run()
方法完成并且线程退出,然后是,它在技术上不必要。但见上文。对于后代, return;
对中断标志没有任何作用。
问题是你的 View
班已被包裹。你确定当你回来时你正在退出 Thread
。也许有人委托给它。 AOP可能会用来做某种仪器。
叫它有什么好处?文章指出应该这样做,因为否则“[...]代码更高的代码将无法找到它[...]”。
通常,当代码被需要中断标志的某种包装代码(委托,AOP等)调用时,不要吞下中断是很重要的。如果你吞咽它,包装将无法使用它。但在这种情况下,没有任何好处。
Thread.State.TERMINATED中的一个线程有什么好处,在应用程序关闭时没有设置中断标志?
没有。一旦线程退出中断状态就毫无价值。实际上,看起来线程死后,中断状态甚至不会持久存在。
Thread thread = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("caught");
}
}
});
thread.start();
thread.interrupt();
System.out.println(thread.isInterrupted());
thread.join();
System.out.println(thread.isInterrupted());
打印:
true
caught
false
你能举个例子说明Runnable以外的代码是否有合理的原因检查中断的标志?
我不能。线程之外没有代码 run()
方法,除非有人在您不知情的情况下将runnable包装在其他代码中。
如果您使用的话可能会发生这种情况 ExecutorService
但在这种情况下,线程的中断状态通过a特别清除 wt.isInterrupted()
在工作开始之前。
再说一次,原因是因为它是一个很好的模式,而这正是软件工程中的重要因素。