java线程异常

Amm*_*mmu 23 java multithreading exception

假设从main方法启动一个线程.如果在线程中抛出异常但在线程内没有处理异常会发生什么?

是否可以将异常传播回main方法?

zac*_*usz 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)
Run Code Online (Sandbox Code Playgroud)

这是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();
Run Code Online (Sandbox Code Playgroud)

要为所有线程设置处理程序,请使用静态方法Thread.setDefaultUncaughtExceptionHandler.


And*_*yle 5

如果异常被该线程中运行的代码捕获并处理,那么它将被处理,但是catch块逻辑被写入.我将在接下来的答案中假设您正在谈论未捕获的异常.

未捕获的异常将导致线程退出.当它冒泡到它的顶部时Thread.run(),将由Thread的UncaughtExceptionHandler处理.默认情况下,这只会将堆栈跟踪打印到控制台.线程本身将在此时退出 - 无论如何它都无法继续,因为它的run()方法已经完成.

因此,如果您希望在主线程中重新引用异常,则可以定义一个UncaughtExceptionHandler来执行此操作(这是一个非常简单的接口),然后Thread.setUncaughtExceptionHandler在生成它之后调用生成的线程,并传入自定义异常处理程序.


编写处理程序的唯一可能棘手的部分是确定将throwable"插入"主线程的位置和方式.如果您的线程没有做其他事情,这并不完全是显而易见的,并且将在很大程度上取决于您如何设计应用程序以及它的并发支持是什么样的.

(另一方面,如果你的主线程正在等待另一个Thread运行,那么它会变得更容易.但在这种情况下,也许你的主线程应该将一个任务提交给一个线程ExecutorService并阻塞一个Future,这将处理所有这些布线/生命周期的东西给你?)