Java多线程的异常捕捉

#(前言)

最近在做一些东西的时候,时常需要使用多线程来提升一下性能,但是在使用线程池的时候会发现无法捕获其中线程的异常,这个该如何处理呢,talk is chep show me the code

#(单线程情况)

对于单线程来说,只需要重写UncaughtException就好了,如下:

/**
 * Author: 47
 */
public class RewriteUncatchtExceptionHandler implements Thread.UncaughtExceptionHandler{
    public void uncaughtException(Thread t, Throwable e) {
        System.out.println("我捕获到了线程池的异常");
    }
}
复制代码
/**
 * Author: 47
 */
public class Task implements Runnable {
    public void run() {
        System.out.println("执行任务");
        int num  = Integer.parseInt("TT");
    }
}
复制代码
复制代码
/**
   * 对于单个线程出现的异常情况可以使用异常处理器,可以捕获到
   */
public static void catchSingleThread() {
        Task task = new Task();
        Thread thread = new Thread(task);
        thread.setUncaughtExceptionHandler(new RewriteUncatchtExceptionHandler());
     thread.start();
 }
复制代码

运行程序,我们发现可以正常的捕获到这个unchecked异常,但是线程池中我们应该怎么处理呢?如下:

#(线程池)

首先我们要重写 ThreadFactory来为每个线程实例化的时候创建一个handler

复制代码
/**
 * Author: 47
 */
public class MyThreadFactory implements ThreadFactory{
    public Thread newThread(Runnable r) {
        Thread t = new Thread(r);
        t.setUncaughtExceptionHandler(new RewriteUncatchtExceptionHandler());
        System.out.println("Thread[" + t.getName() + "] created.");
        return t;
    }
}
复制代码
/**
  * 虽然从写ThreadFactory以后,可以捕获到异常,但是只能是execute,而submit还是不行  how to choose one
  */
public static void catchedExecutor() { ExecutorService executorService = Executors.newCachedThreadPool(new MyThreadFactory()); executorService.execute(new Task()); executorService.shutdownNow(); }

现在问题来了,就是这样虽然可以捕获到异常,但是只能是使用execute的时候可以,使用submit的时候是不成功的,那么我们应该如何选择呢?

/**
 * how to choose submit() or execute()
 * There is a difference concerning exception/error handling.A task queued with execute() that generates some Throwable will cause the UncaughtExceptionHandler
 * for the Thread running the task to be invoked. The default UncaughtExceptionHandler, which typically prints the Throwable stack trace to System.err, will be
 * invoked if no custom handler has been installed.On the other hand, a Throwable generated by a task queued with submit() will bind the Throwable to the Future
 * that was produced from the call to submit(). Calling get() on that Future will throw an ExecutionException with the original Throwable as its cause (accessible
 * by calling getCause() on the ExecutionException).
 */

意思就是说二者最大的区别就是异常处理上,在execute的时候,如果你没有实现一个handler,那么他就使用默认的handler来处理异常,你要是实现了一个handler

他就会使用的实例化的handler,但是对于submit来说,异常是绑定到Future上了,但是调用future.get()的时候,这些异常才会给你抛出来,意味着你自己定义的handler

其实是无效的。

posted @   47号Gamer丶  阅读(439)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示