在我们的应用程序中,我们让线程执行特定操作。 收到事件后,我们需要中断正在进行的线程。 这些线程将通过调用“Thread.currentThread()。isInterrupted()”来检查它们的中断状态, 如果它被中断,则线程通过从run方法返回来停止。
我们现在看到的问题是这些线程可以在一个对象上等待()。 如果线程在对象上的wait()时被中断, 线程中断状态被重置并抛出InterruptedException。
由于 1)我们有很多地方线程可以在一个对象上等待 2)线程访问可以在对象上等待的其他对象的方法
我们决定覆盖中断()& isInterrupted()方法。 代码看起来像
public class MyThread extends Thread {
private boolean isInterrupted = false;
@Override
public void interrupt() {
isInterrupted = true;
super.interrupt();
}
@Override
public boolean isInterrupted() {
return isInterrupted;
}
public void run() {
.........
.........
try {
object1.wait();
} catch (InterruptedException e) {
/* if interrput() is not overrided, the interrupted flag
would be reset */
}
if(Thread.currentThread().isInterrupted()) {
/* if interrupt is not overrided, isInterrupted would return
false and the thread would continue to run. */
return;
}
object2.method1(); // method1() can also wait on another object
/* In method1() also we would need to check isInterrupted and get out
quickly as soon as possible. This method1() will also be used by
other threads which will not be interrupted. */
if(Thread.currentThread().isInterrupted()) {
return;
}
.........
.........
}
}
所以我的问题是
1)如上所述覆盖interrupt()和isInterrupted()是一个很好的代码吗?
2)当覆盖interrupt()时我们应该保持相同的行为,即throw 中断和其他异常,如java doc of interrupt()方法中所述 在Thread类中?实际上我们需要等待被中断的线程 但是要设置的中断标志。
3)Thread.interrupted()方法是静态的。 有了上面的重写,我们不应该使用这种方法吗?
答案 0 :(得分:6)
首先,重写这些方法是一个非常糟糕的主意。
其次,我不明白为什么你的生活如此艰难:
try {
doSomethingThatCanBlock();// e.g. wait()
}
catch(InterruptedException ex) {
Thread.currentThread().interrupt(); // restore interrupt state
}
现在,下次检查Thread
的中断状态时,它会告诉您相应的状态。就是这样。
答案 1 :(得分:0)
如果线程在对象的wait()中被中断,则线程中断状态将被重置并抛出InterruptedException。
恕我直言这句话表明你根本不需要任何中断。中断可以用来中止线程的执行,你似乎不想要它。传递一些消息......如果您想要灵活,请尝试EventBus。它允许您向发件人一无所知的程序部分发送消息。
也许你正在看一些全局变量 1 。请注意,使用Thread.interrupt
也会处理全局变量(面对ThreadPool
时变得无法使用)。
1包装成单身或类似物。
答案 2 :(得分:0)
根据您的评论,由于第三方jar未重新设置中断状态,您被迫覆盖方法。
总的来说,正如@Holger所提到的,捕获InterruptedException
的方法应该恢复状态。
如果第三方jar没有设置状态,为什么不在第三方方法调用后重置标志?
thirdPartyInstance.method1();
if (Thread.currentThread().isInterrupted()){
Thread.interrupted();
}
这样您就可以将您的工作用作Runnable
而非实际Thread
(您不需要覆盖这些方法),您可以使用Thread.currentThread().isInterrupted()
停止的方式你的主题。
最后 - 如果您计划继续扩展Thread并重写这些方法,
将您的isInterrupted()
方法修改为
@Override
public boolean isInterrupted() {
return isInterrupted || super.isInterrupted();
}
如果线程状态由Thread.interrupted();
清除,那么。