2011-07-12 115 views
21

假设线程是从主方法启动的。如果在线程中抛出异常但在线程内未处理异常会发生什么?java线程异常

是否有可能将异常传播回主方法?

回答

32

我们正在讨论从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设置处理程序。

0

如果异常不被try {} catch (Exception e){}处理,那么它会被引发并抛出到被调用的函数。

如果是单独的独立线程,你不能将它传播给对象,它是不是线程

或者其他一些信息,这里的家长:How to throw a checked exception from a java thread?

0

通常情况下,如果你不自己实现异常,当发生一些异常时,它会关闭执行。

+0

只有它发生的线程 –

3

不,它不能。当你想到它时,main()方法可能在几天前​​完成。

任何来自线程的未捕获异常都会传播到线程的UncaughtExceptionHandler。如果没有定义的话,它会转到线程组的处理程序,如果没有设置,它会转到默认处理程序。

+0

关于'days ago'的答案中的第一行有助于更好地理解问题。实际上,多个线程可以像发生(容易)共享数据的单独进程那样工作。可以使用单独的进程和共享内存构建完全相同的模型(有些难度较大)。 – kevinarpe

0

该例外被UncaughtExceptionHandler捕获。如果你愿意的话,你可以在那里捕获它并将它传播回主线程​​。

5

如果异常被该线程中运行的代码捕获并处理,那么将处理该异常,但会写入catch块逻辑。我会假设这个答案的其余部分是关于未捕获的异常。

未捕获的异常将导致线程退出。当它泡到Thread.run()的顶部时,将由线程的UncaughtExceptionHandler处理。默认情况下,这只会将堆栈跟踪打印到控制台。线程本身将在此处退出 - 它无法继续,因为它的run()方法已完成。所以如果你想在你的主线程中重新进行异常处理,你可以定义一个UncaughtExceptionHandler来做这件事(这是一个非常简单的接口),然后在创建线程后在产生的线程上调用Thread.setUncaughtExceptionHandler,传入你的定制异常处理程序


唯一对编写处理潜在棘手的部分是确定在哪里和你要去究竟如何“插入”的抛出到你的主线程。如果你的线程不做其他事情,这将不是很明显,而且很大程度上取决于你如何设计你的应用程序以及它的并发支持是什么样的。 (如果另一方面你的主线程正在等待另一个线程运行,那么它变得更容易了,但在这种情况下,也许你的主线程应该提交一个任务给线程ExecutorService并阻塞一个Future,它会处理所有这些布线/生命周期的东西吗?)

相关问题