Java 线程异常处理

如果我们调用一个线程处理任务,但是当线程发生异常的时候我们调用线程的地方无法捕捉到异常。
用例子验证:我在main中把调用线程的代码放到try-catch里面,但是结果却没有捕捉到任何异常。

package thread;
class MRunnable implements Runnable{

    @Override
    public void run() {
        throw new RuntimeException("This is an exception from Runnable");
        
    }
    
}

public class TestException {

    public static void main(String[] args) {
        try{
            new Thread(new MRunnable2()).start();
            
        }catch (Exception e) {
            System.out.println("catch: "+e.getMessage());
        }

    }

}

执行结果:

Exception in thread "Thread-0" java.lang.RuntimeException: This is an exception from Runnable
    at thread.MRunnable2.run(TestException.java:6)
    at java.lang.Thread.run(Unknown Source)

从结果看,console并没有打印出“catch:”,证明没有捕捉到。
怎么才能在线程外捕捉到异常呢?
Thread类中有个UncaughtExceptionHandler接口,如果有异常,JVM会调用dispatchUncaughtException()方法。

  /**
     * Dispatch an uncaught exception to the handler. This method is
     * intended to be called only by the JVM.
     */
    private void dispatchUncaughtException(Throwable e) {
        getUncaughtExceptionHandler().uncaughtException(this, e);
    }

因此我们只要一个实现了UncaughtExceptionHandler接口的类就可以了。

package thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

class MRunnable implements Runnable {

    @Override
    public void run() {
        throw new RuntimeException("This is an exception from Runnable");

    }

}

class MThreadFactory implements ThreadFactory {

    @Override
    public Thread newThread(Runnable r) {
        Thread thread = new Thread(r);
        thread.setUncaughtExceptionHandler(new MUncaughtExceptionHandler());
        return thread;
    }

}

class MUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {

    @Override
    public void uncaughtException(Thread t, Throwable e) {
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>");
        System.out.println("catch: "+e.getMessage());
        System.out.println("<<<<<<<<<<<<<<<<<<<<<<<<<<<");
    }

}

public class TestException {

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool(new MThreadFactory());

        executorService.execute(new MRunnable());

    }

}

执行结果:

>>>>>>>>>>>>>>>>>>>>>>>>>>>
catch: This is an exception from Runnable
<<<<<<<<<<<<<<<<<<<<<<<<<<<
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,953评论 18 399
  • 下面是我自己收集整理的Java线程相关的面试题,可以用它来好好准备面试。 参考文档:-《Java核心技术 卷一》-...
    阿呆变Geek阅读 14,999评论 14 507
  • (一)Java部分 1、列举出JAVA中6个比较常用的包【天威诚信面试题】 【参考答案】 java.lang;ja...
    独云阅读 11,937评论 0 62
  • 浮尘人寰心难欺,奈何今朝世事饥。 物重命轻躁常在,好高骛远性难移。 诚惧意恐喧嚣梦,风雨济州行无期。 宁求片厘清心...
    M一介布衣阅读 1,287评论 0 0
  • 曼陀有三类工作 一、招生队员: 工作职责:在校园食堂或虹远宿舍等地发校历,邀同学体验课程。 薪酬: 底薪20元/小...
    梁绛阅读 4,012评论 0 0