出于某种原因,我对以下内容感到困惑:
假设在Thread A
完成处理后,我Thread B
绝对需要执行。{
一种方法是Thread A
加入Thread B
琐碎的例子:
public class MainThread {
public static void main(String[] args){
Thread b = new Thread (new SomeRunnable(args[0]));
b.start();
try {
b.join();
} catch(InteruptedException e) {
}
// Go on with processing
}
}
我的问题如下:在这种情况下处理异常的正确方法是什么?
在我看到的各种例子中,即使在教科书中,也忽略了例外
因此,如果Thread A
需要确保Thread B
在进行处理之前已完全完成,如果由于异常而导致捕获结束,那么Thread B
是否仍可能实际存在可运行/运行?那么处理这个异常的最佳方法是什么?
答案 0 :(得分:2)
在这种情况下处理异常的正确方法是什么?
任何时候你得到InterruptedException
当前线程都应该认为自己被打断了。通常,这意味着线程应该在自身之后清理并退出。在你的情况下,主线程被另一个线程中断,应该可能会中断它依次启动的Thread a
,然后退出。
虽然你应该忽略中断,但我认为这是一个不好的做法。如果你使用中断作为线程的某种信号,那么我会设置一些volatile boolean
标志。
就捕捉InterruptedException
时的最佳做法而言,我通常会这样做:
try {
...
} catch(InterruptedException e){
// a good practice to re-enable the interrupt flag on the thread
Thread.currentThread().interrupt();
// in your case you probably should interrupt the Thread a in turn
a.interrupt();
// quit the thread
return;
}
由于捕获InterruptedException
会清除线程的中断标志,因此在catch块中重新启用中断标志始终是个好主意。
在我看到的各种例子中,即使在教科书中,例外也会被忽略。
事实上。忽略任何异常是非常糟糕的做法,但它始终会发生。不要屈服于黑暗势力!
可能是线程B实际上仍然可以运行/运行的情况吗?
Thread B
当然可以继续运行。它是调用已被中断的join()
的主线程。
答案 1 :(得分:2)
首先,您必须了解导致此异常的原因。当前不推荐在某个线程上调用stop()
,而是当您想要通过调用thread.interrupt()
来停止一个中断它的线程时。这对线程(!)没有影响,线程必须偶尔显式检查interrupted
标志并正常停止处理。
但是,如果线程休眠,等待锁或另一个线程(通过使用示例中的join()
),则无法立即或经常检查此标志。在这些情况下,JVM将从阻塞方法(让它为join()
)发出一个异常信号,表明有人试图打断它。通常,您可以忽略该异常(意思是 - 不记录它) - 这是重要的副作用。例如,摆脱循环:
public void run() {
try {
while(!isInterrupted()) {
Thread.sleep(1000);
//...
} catch(InterruptedException e) {
//no need to log it, although it's a good idea.
}
}
您没有记录该异常并不是问题 - 但是您从循环中转义,有效地终止了该线程。
现在回到你的问题。当您的Thread A
被中断时,它意味着请求终止它的其他一些线程,可能是因为整个JVM关闭或Web应用程序正在取消部署。在这种情况下,除了清理之外,你不应该做任何事情。
此外,它很可能意味着Thread B
仍在运行。但是JVM试图说的是:“危险!危险!停止等待你正在等待的任何事情并运行!”。