如何在Java中将异常传播到调用线程中

12 浏览
0 Comments

如何在Java中将异常传播到调用线程中

我有一个Java主类,在这个类中,我启动了一个新的线程,在主类中,它等待直到线程结束。在某个时刻,我从线程中抛出了一个运行时异常,但是我无法在主类中捕捉到从线程抛出的异常。

以下是代码:

public class Test extends Thread {
  public static void main(String[] args) throws InterruptedException {
    Test t = new Test();
    try {
      t.start();
      t.join();
    } catch(RuntimeException e) {
      System.out.println("** 从主类抛出的运行时异常");
    }
    System.out.println("主类停止");
  }
  @Override
  public void run() {
    try {
      while(true) {
        System.out.println("** 开始");
        sleep(2000);
        throw new RuntimeException("来自线程的异常");
      }
    } catch (RuntimeException e) {
      System.out.println("** 从线程抛出的运行时异常");
      throw e;
    } catch (InterruptedException e) {}
  }
}

有人知道为什么吗?

0
0 Comments

这篇文章将讨论在Java中如何将异常传播到调用线程,首先我们来看一下异常在线程中的状态转换。下面的图示展示了线程在异常发生与否时的状态转换:

Threads and Exception Handling

图片来源: http://www-public.imtbs-tsp.eu/~gibson/Teaching/CSC7322/L8-ExceptionsAndThreads.pdf

你创建了这个图吗?如果不是,那么它的来源是什么?

0
0 Comments

Java中如何将异常传播给调用线程?

Java中的异常是线程局部的,因此主线程实际上无法看到run方法。建议您阅读更多关于线程工作原理的内容,但是简单总结一下:调用start会启动一个与主线程完全无关的不同线程。调用join只是等待该线程完成。在线程中抛出但从未捕获的异常会终止该线程,这就是为什么join在主线程上返回,但异常本身会丢失的原因。

如果您想要知道这些未捕获异常,可以尝试以下方法:

Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
    public void uncaughtException(Thread t, Throwable e) {
        System.out.println("Caught " + e);
    }
});

有关未捕获异常处理的更多信息可以在这里找到。

我喜欢这个方法!使用静态方法Thread.setDefaultUncaughtExceptionHandler()设置处理程序也可以捕获主线程中的异常。

0
0 Comments

在Java中,如果想要将异常传播到调用线程,可以使用Thread.UncaughtExceptionHandler。以下是一个示例代码:

Thread.UncaughtExceptionHandler h = new Thread.UncaughtExceptionHandler() {
    public void uncaughtException(Thread th, Throwable ex) {
        System.out.println("Uncaught exception: " + ex);
    }
};
Thread t = new Thread() {
    public void run() {
        System.out.println("Sleeping ...");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            System.out.println("Interrupted.");
        }
        System.out.println("Throwing exception ...");
        throw new RuntimeException();
    }
};
t.setUncaughtExceptionHandler(h);
t.start();

如果想要将异常传播到上一层级,可以将异常保存到一个volatile变量中,使得上一层级可以在异常处理器中看到。在外部,可以检查变量是否为null,如果不为null,则抛出异常。或者可以通过扩展UncaughtExceptionHandler,添加一个volatile字段,并将异常存储在其中。

有人询问如何在不停止线程的情况下捕获线程内部的异常。然而,由于异常无法跨线程边界抛出,因此无法将异常直接抛到上一层级。在这种情况下,最好的方法是让异常处理器将未捕获的异常对象放入一个队列中,并让主线程定期检查队列以确定是否有异常抛出。

,要将异常传播到调用线程,可以使用Thread.UncaughtExceptionHandler。要将异常传播到上一层级,可以使用volatile变量或扩展UncaughtExceptionHandler并将异常存储在其中。如果要在不停止线程的情况下捕获线程内部的异常,可以使用异常处理器将异常对象放入队列中,并由主线程定期检查队列。

0