【并发编程】线程池任务抛异常会怎么样?

news/2025/2/24 13:33:21

一、先说结论

得看线程池的实现,JUC 的线程池(ThreadPoolExecutor)的话

  1. 不会影响其他的线程
  2. 若是 submit 方法,或者任务为 future 任务,异常只有在 get 的时候才会抛出
  3. 若是 execute + runnable 任务,异常就会抛出,线程挂掉后,线程池移除该线程并创建一个新的线程

若通过 submit 提交任务,会将任务封装到 future 里面或者原任务本身就是 future 任务,而 future 的 run 方法执行的时候,抛出的异常在其内部会被捕获,等到 get 方法的时候才会抛出。

execute + runnable,并没有涉及 future,虽然异常会被捕获,但也以为被重新抛出,导致线程中断,线程池需要移除线程,并创建新的线程

二、submit、execute 方法

在这里插入图片描述

在这里插入图片描述

线程运行任务核心代码

java">final void runWorker(Worker w) {
    Thread wt = Thread.currentThread();
    Runnable task = w.firstTask;
    w.firstTask = null;
    w.unlock(); // allow interrupts
    boolean completedAbruptly = true;
    try {
        while (task != null || (task = getTask()) != null) {
            w.lock();
            // If pool is stopping, ensure thread is interrupted;
            // if not, ensure thread is not interrupted.  This
            // requires a recheck in second case to deal with
            // shutdownNow race while clearing interrupt
            if ((runStateAtLeast(ctl.get(), STOP) ||
                 (Thread.interrupted() &&
                  runStateAtLeast(ctl.get(), STOP))) &&
                !wt.isInterrupted())
                wt.interrupt();
            try {
                beforeExecute(wt, task);
                try {
                    task.run();
                    afterExecute(task, null);
                } catch (Throwable ex) {
                    afterExecute(task, ex);
                    throw ex;
                }
            } finally {
                task = null;
                w.completedTasks++;
                w.unlock();
            }
        }
        completedAbruptly = false;
    } finally {
        processWorkerExit(w, completedAbruptly);
    }
}

三、异常处理

比较全面的处理,主要是,afterExecute 方法,这个哪怕抛出异常也会执行

java">new ThreadPoolExecutor(
    IO_CORE,
    IO_MAX,
    KEEP_ALIVE_SECOND,
    TimeUnit.SECONDS,
    // 任务队列存储超过核心线程数的任务
    new LinkedBlockingDeque<>(QUEUE_SIZE),
    r -> {
        Thread thread = new Thread(r);
        thread.setDaemon(Boolean.TRUE);
        thread.setName(String.format("%s, message-process-thread-%d", threadName, NUM.getAndIncrement()));
        return thread;
    }
) {
    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        // 若 t 不为 null,正常处理
        if (Objects.nonNull(t)) {
            log.error(t.getMessage());
        }
        // 特别注意的是 futureTask 在 run 的时候不会立即抛异常,而是吞掉,在调用 get 的时候才能抛出
        // 如果是 submit 提交,原本的任务被封装成 futureTask,异常不会在 t 里,而是在 futureTask 里(但原本的任务是 futureTask 的话,则应该是原本的任务 get 的时候才会抛异常)
        // 如果是 execute,则 r 还是原来的任务,但不排除 r 本来就是 futureTask,那么其错误信息本来就应该通过 get 获取,在这里处理一下也无妨,不影响原本的处理结果即可
        // 原任务为 futureTask 的时候,get 时一定要处理异常
        if (r instanceof Future<?> futureTask) {
            try {
                futureTask.get();
            } catch (Exception e) {
                log.error(e.getMessage());
            }
        }
    }
};
log.info("线程池已经初始化");
EXECUTOR.allowCoreThreadTimeOut(Boolean.TRUE);
// JVM 关闭时的钩子函数
Runtime.getRuntime().addShutdownHook(
    new ShutdownHookThread("IO 密集型任务线程池", (Callable<Void>) () -> {
        shutdownThreadPoolGracefully(EXECUTOR);
        return null;
    })
);

http://www.niftyadmin.cn/n/5864390.html

相关文章

DataWhale组队学习 wow-agent task4

整体概念总结 智能体的实现方法 安装与配置&#xff1a;安装和配置MetaGPT&#xff0c;包括Python环境的准备、MetaGPT的安装&#xff08;通过pip或git拉取代码&#xff09;&#xff0c;以及配置大模型API&#xff08;如智谱、科大讯飞、百度千帆等&#xff09;。 单动作单智能…

腾讯SQL面试题解析:如何找出连续5天涨幅超过5%的股票

腾讯SQL面试题解析:如何找出连续5天涨幅超过5%的股票 作者:某七年数据开发工程师 | 2025年02月23日 关键词:SQL窗口函数、连续问题、股票分析、腾讯面试题 一、问题背景与难点拆解 在股票量化分析场景中,"连续N天满足条件"是高频面试题类型。本题要求在单表stoc…

golang设计模式-函数选项模式

函数选项模式 什么是函数选项模式 在 Go 语言中&#xff0c;函数选项模式是一种优雅的设计模式&#xff0c;用于处理函数的可选参数。它提供了一种灵活的方式&#xff0c;允许用户在函数调用时传递一组可选参数&#xff0c;而不是依赖于固定数量和顺序的参数列表。 哪些地方…

冒泡排序(详解)c++

冒泡排序(Bubble Sort)也是⼀种简单的排序算法。它的⼯作原理是每次检查相邻两个元素&#xff0c;如果前⾯ 的元素与后⾯的元素满⾜给定的排序条件&#xff0c;就将相邻两个元素交换。当没有相邻的元素需要交换时&#xff0c; 排序就完成了。 由于在算法的执⾏过程中&#xff0…

H5 火柴人科目三和GitHub获取仓库点星星的用户列表发生了艺术的碰撞

先看效果&#xff0c;代码写的比较乱&#xff0c;有待优化 效果 https://linyisonger.github.io/H5.Examples/?name./089.%E7%9C%8B%E6%98%9F%E6%98%9F%E7%9A%84%E8%88%9E%E8%80%85.html 思路 看起来很简单&#xff0c;实则也不是很难&#xff0c;就是需要思路要打开。 一…

QT 基础知识点

1.基础窗口类QMainWindow qDialog Qwidget 随项目一起创建的窗口基类有三个可选QMainWindow qDialog Qwidget 1.1 Qwidget 是所有窗口的基类&#xff0c;只要是他的子类&#xff0c;或子类的子类&#xff0c;都具有他的属性。 右键项目 Add New -> Qt qt设计师界面类&am…

2025年SCI一区智能优化算法:混沌进化优化算法(Chaotic Evolution Optimization, CEO),提供MATLAB代码

一、混沌进化优化算法 https://github.com/ITyuanshou/MATLABCode 1. 算法简介 混沌进化优化算法&#xff08;Chaotic Evolution Optimization, CEO&#xff09;是2025年提出的一种受混沌动力学启发的新型元启发式算法。该算法的主要灵感来源于二维离散忆阻映射的混沌进化过…

DINOv2 + yolov8 + opencv 检测卡车的可拉拽雨覆是否完全覆盖

最近是接了一个需求咨询图像处理类的&#xff0c;甲方要在卡车过磅的地方装一个摄像头用检测卡车的车斗雨覆是否完全&#xff0c; 让我大致理了下需求并对技术核心做下预研究 开发一套图像处理软件&#xff0c;能够实时监控经过的卡车并判断其车斗的雨覆状态。 系统需具备以下…