什么情况会导致Java线程意外返回?

3

我正在开发一个分布式多线程应用程序,其中线程在分布式任务执行过程中似乎会随机返回。假设该应用程序中的每个线程都使用与下面代码块相同的基本代码:

public class ExecutionThread extends Thread{
    @Override
    public void run(){
        while(true){
            try{
                //task submitter app dumps all Tasks in to a queue.  We retrieve
                //those tasks here one-by-one and run them:
                Task t = priorityBlockingQueue.take();

                //execute is abstract, so it could potentially do anything here:
                t.execute(); 
            } catch(Throwable e){
                //task submitter app will be able to access the Throwable later:
                t.setUncaughtThrowable(e); 
            }
        }
    }
}

需要注意的是,Task类是抽象的且非常简单 - 它只有一个execute()方法是抽象的,因此我觉得没有必要在这里发布它的代码。

我知道在JVM中可能会发生一些疯狂的事情,但对我来说,这段代码似乎相当牢固,因为除非运行它的JVM死亡,否则该线程不应该返回。实际上,我们看到一些线程仍然返回而其相应的JVM并未死亡,并且无法确定原因。更糟糕的是,我们无法看到这些线程的控制台,因为它们作为远程计算机上的子进程被生成。我们已经尝试记录throwable,但没有任何东西被打印到文件中。你有什么想法,可能会导致这个线程仍然返回吗?


3
这里的“return”是什么意思?是指没有任何例外地退还吗? - Jon Skeet
是的 - 没有任何异常被抛出,run()方法只是结束了。 - CodeBlind
setUncaughtThrowable 是什么? - Snicolas
@BenLawry - 那么这是如何工作的呢?假设,任务包含一个提交者引用,并且可以以某种方式向其发出信号,表明任务已完成/失败。里面有什么?在捕获时调用的事件吗?如果任务没有异常地完成,提交者如何被通知?这里似乎缺少了很多东西... - Martin James
@MartinJames 更不用说他可能会得到一个编译器错误,指出在catch子句中t无法解析为一种类型。 - John Vint
显示剩余2条评论
1个回答

4

catch 子句中必须有一个 Exception


3
不行。如果在您的 catch 子句中抛出异常,则根据您的代码,它将向外传递。 - Paul Nikonowicz
1
@Daniel Paul 是正确的。如果 setUncaughtThrowable() 方法中出现了 NullPointerException,怎么办? - John Vint
1
@BenLawry 除非我们了解更多情况,否则我们只能猜测是否出现了OutOfMemoryError或StackOverflowError。 - John Vint
1
你可以尝试以调试模式运行JVM,这样当再次发生此类情况时,你就可以查看线程了。 - Paul Nikonowicz
1
@BenLawry,你说得完全正确,你正在观察到捕获Throwable的根本问题。我建议捕获RuntimeException并让任务处理它。 - John Vint
显示剩余9条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接