加入线程时处理异常的最佳方法

时间:2012-07-19 16:57:02

标签: java multithreading exception-handling concurrency

出于某种原因,我对以下内容感到困惑:
假设在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是否仍可能实际存在可运行/运行?那么处理这个异常的最佳方法是什么?

2 个答案:

答案 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试图说的是:“危险!危险!停止等待你正在等待的任何事情并运行!”。