为啥在这个多线程示例中没有捕获到异常?

Posted

技术标签:

【中文标题】为啥在这个多线程示例中没有捕获到异常?【英文标题】:Why the exception is not caught in this multithread example?为什么在这个多线程示例中没有捕获到异常? 【发布时间】:2021-04-13 10:31:09 【问题描述】:

我试图了解异常如何在多线程中传播。

问题

在下面的例子中。 为什么RuntimeException 异常没有被捕获

`System.out.println("Exception handled " + e); 

给定代码

package p05_Interrupt;

public class D05_Interrupt1 extends Thread 
  public void run()  
    try 
      Thread.sleep(1000);
      System.out.println("task");
     catch (InterruptedException e) 
      throw new RuntimeException("Thread interrupted..." + e);
    
  

  public static void main(String args[]) 
    D05_Interrupt1 t1 = new D05_Interrupt1();
    t1.start();
    try 
      t1.interrupt();
     catch (Exception e) 
      System.out.println("Exception handled " + e); // Why not print this line 
    
  

1st example in JavaTpoint "Example of interrupting a thread that stops working"

输出

Exception in thread "Thread-0" java.lang.RuntimeException: Thread interrupted...java.lang.InterruptedException: sleep interrupted
    at p05_Interrupt.D05_Interrupt1.run(D05_Interrupt1.java:9)

是不是因为这是多线程,所以在线程t1打印异常,隐藏main()线程的输出?

我还尝试在 public void run() throws RuntimeException 添加 throws 并没有改变任何东西。

【问题讨论】:

【参考方案1】:

你不能(像那样)在 main 线程中捕获线程抛出的异常。但是,您可以实现 Thread.UncaughtExceptionHandler 来实现。

公共静态接口 Thread.UncaughtExceptionHandler 接口用于 当线程由于未捕获而突然终止时调用的处理程序 例外。

当线程由于未捕获的异常而即将终止时, Java 虚拟机将向线程查询它的 UncaughtExceptionHandler 使用 Thread.getUncaughtExceptionHandler() 并将调用处理程序的 uncaughtException 方法,传递 线程和异常作为参数。 如果线程还没有它的 UncaughtExceptionHandler 显式设置,然后是它的 ThreadGroup 对象 充当其 UncaughtExceptionHandler。如果 ThreadGroup 对象没有 处理异常的特殊要求,可以转发 对默认未捕获异常处理程序的调用。

public class D05_Interrupt1 extends Thread 
        implements Thread.UncaughtExceptionHandler 

    public void run() 
        try 
            Thread.sleep(1000);
            System.out.println("task");
         catch (InterruptedException e) 
            throw new RuntimeException("Thread interrupted..." + e);
        
    

    public static void main(String args[]) 
        D05_Interrupt1 t1 = new D05_Interrupt1();
        Thread.setDefaultUncaughtExceptionHandler(t1);
        t1.start();
        t1.interrupt();
    

    @Override
    public void uncaughtException(Thread t, Throwable e) 
        System.out.println("Exception handled " + e); // Why not print this line
    

输出:

Exception handled java.lang.RuntimeException: Thread interrupted...java.lang.InterruptedException: sleep interrupted

【讨论】:

以上是关于为啥在这个多线程示例中没有捕获到异常?的主要内容,如果未能解决你的问题,请参考以下文章

为啥不能在主线程中直接捕获和处理工作线程抛出的异常?

多线程捕获线程中的异常

C#多线程开发-处理异步操作中的异常

多线程情况下如何捕获线程中的异常?

当其中一个线程中存在未捕获的异常时,Python 多线程程序不会退出

.net捕获全局异常并且记录日志多线程方式发送邮件提醒