如何从线程中捕获异常

14 浏览
0 Comments

如何从线程中捕获异常

我有一个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("** RuntimeException from main");
    }
    System.out.println("Main stoped");
  }
  @Override
  public void run()
  {
    try
    {
      while(true)
      {
        System.out.println("** Started");
        sleep(2000);
        throw new RuntimeException("exception from thread");
      }
    }
    catch (RuntimeException e)
    {
      System.out.println("** RuntimeException from thread");
      throw e;
    } 
    catch (InterruptedException e)
    {
    }
  }
}

有人知道原因吗?

admin 更改状态以发布 2023年5月21日
0
0 Comments

这是因为异常属于线程局部变量,而主线程并没有实际看到run方法。我建议您更多地了解线程如何工作,但简单概括一下:您对start的调用启动了一个完全不相关的线程,与主线程无关。对join的调用只是等待它结束。在线程中抛出的未被捕获的异常会终止它,这就是为什么join在主线程上返回,但异常本身会丢失的原因。

如果您想了解这些未捕获的异常,可以尝试以下内容:

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

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

0
0 Comments

使用 Thread.UncaughtExceptionHandler

Thread.UncaughtExceptionHandler h = new Thread.UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread th, Throwable ex) {
        System.out.println("Uncaught exception: " + ex);
    }
};
Thread t = new Thread() {
    @Override
    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();

0