3

出于某种原因,我对以下内容感到困惑:
假设我在完成处理Thread A绝对需要执行。 一种方法是加入. 简单的例子: Thread B
Thread AThread 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可能仍然是实际可运行/正在运行的情况?那么处理此异常的最佳方法是什么?

4

2 回答 2

2

在这种情况下处理异常的正确方法是什么?

任何时候你得到一个InterruptedException当前线程都应该认为自己被中断了。通常,这意味着线程应该自行清理并退出。在您的情况下,主线程被另一个线程中断,并且可能应该中断Thread a它依次启动的线程,然后退出。

尽管是否应该忽略中断取决于您,但我建议这是一种不好的做法。如果您将中断用作线程的某种信号,那么我会设置一些volatile boolean标志。

就 catch 时的最佳实践而言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()被中断的是主线程。

于 2012-07-19T17:04:18.653 回答
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 想说的是:“危险!危险!停止等待你等待的任何东西并运行! ”。

于 2012-07-19T17:07:53.523 回答