假设从main方法启动一个线程。如果在线程中抛出异常但在线程中没有处理异常会发生什么?
是否可以将异常传播回main方法?
答案 0 :(得分:35)
我们正在讨论从Thread.run
方法抛出的未经检查的异常。
默认情况下,您会在系统错误中得到这样的信息:
Exception in thread "Thread-0" java.lang.RuntimeException
at Main$1.run(Main.java:11)
at java.lang.Thread.run(Thread.java:619)
这是printStackTrace对未处理异常的结果。要处理它,您可以添加自己的UncaughtExceptionHandler:
Thread t = new Thread(new Runnable(){
public void run() {
throw new RuntimeException();
}
});
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
System.out.println("exception " + e + " from thread " + t);
}
});
t.start();
要为所有线程设置处理程序,请使用静态方法Thread.setDefaultUncaughtExceptionHandler
。
答案 1 :(得分:5)
如果异常被该线程中运行的代码捕获并处理,那么它将被处理,但是catch
块逻辑被写入。对于本答复的其余部分,我将假设您正在谈论未捕获的例外情况。
未捕获的异常将导致线程退出。当它冒泡到Thread.run()
的顶部时,它将由线程的UncaughtExceptionHandler处理。默认情况下,这只会将堆栈跟踪打印到控制台。线程本身将在此时退出 - 无论如何它都无法继续,因为它的run()
方法已经完成。
因此,如果您希望在主线程中重新引用异常,可以定义一个UncaughtExceptionHandler来执行此操作(这是一个非常简单的接口),然后在生成后在生成的线程上调用Thread.setUncaughtExceptionHandler
,传入自定义异常处理程序。
编写处理程序的唯一可能棘手的部分是确定将throwable“插入”主线程的位置和方式。如果您的线程没有做其他事情,这并不完全是显而易见的,并且将在很大程度上取决于您如何设计应用程序以及它的并发支持是什么样的。
(另一方面,如果你的主线程正在等待另一个Thread运行,那么它会变得更容易。但在这种情况下,也许你的主线程应该将一个任务提交给一个线程ExecutorService
阻塞Future
,它将为你处理所有这些布线/生命周期的东西?)
答案 2 :(得分:3)
不,它不能。当你考虑它时,main()
方法可能在几天前完成了。
线程中任何未捕获的异常都会传播到线程的UncaughtExceptionHandler
。如果没有定义,它将转到线程组的处理程序,如果没有设置,它将转到默认处理程序。
答案 3 :(得分:0)
如果try {} catch (Exception e){}
未处理异常,则会将其引发并抛出到调用的函数。
如果它是单独的独立线程,则无法将其传播到非线程父
的对象或其他一些信息:How to throw a checked exception from a java thread?
答案 4 :(得分:0)
通常情况下,如果您没有自己实现异常,当发生异常时,它会关闭执行。
答案 5 :(得分:0)
UncaughtExceptionHandler捕获了异常。如果你愿意的话,你可以把它传播回主线程。