【异常】捕获线程池执行任务时产生的异常

news2025/1/16 8:14:18

前言:

        在编写程序时,我们为了充分利用多核CPU、加快接口响应速度,通常会使用线程池来处理请求,但线程池执行任务过程中难免会出现异常,导致请求失败。那如果我们想在任务发生异常后捕获异常,并做一些”善后“操作,该如何做呢?

捕获方案:

        1、try、catch:

public class ExceptionHandle {
    public static void main(String[] args) {

        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                1,
                2,
                30,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>()
        );

        executor.execute(() -> {
            try {
                //模拟业务代码出现异常
                int i = 1 / 0;
            }catch (Exception e){

                System.err.println(e.getMessage());
            }
        });
        executor.shutdown();
    }
}

        原理:在编码时提前预知业务代码可能会发生异常,并用try块捕获业务异常,并在catch块做善后工作。        

        2、FutureTask:

public class ExceptionHandle {
    public static void main(String[] args) {


        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                1,
                2,
                30,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>()
        );

        Callable<Integer> callable = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                //模拟业务代码出现异常
                return 1/0;
            }
        };
        FutureTask<Integer> task = new FutureTask<Integer>(callable);
        executor.submit(task);
        try {
            task.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            //这里捕获的是真正的业务异常
            System.err.println(e.getCause().getMessage());
        }
        executor.shutdown();
    }
}

       原理:FutureTask技能作为任务提交给线程执行,也能像Future一样通过get()方法获取任务执行结果。如果任务正常执行,那么返回的就是结果对象,如果执行出现异常,返回的就是异常对象;当发生异常时,try块就能捕获异常,并在catch块做相应处理。get()方法实现如下

//可能会抛出InterruptedException、ExecutionException
public V get() throws InterruptedException, ExecutionException {
        int s = state;
        if (s <= COMPLETING)
            s = awaitDone(false, 0L);
        return report(s);
    }

        InterruptedException是线程在等待执行结果时,被其它线程打断所产生的异常。

        用Future接口获取submit()方法的返回结果也能达到同样的效果,对FutureTask不太了解的话,可以看我的这篇博客:【Java】浅析FutureTask的核心方法get-CSDN博客

        3、ThreadFactor:

​
public class ExceptionHandle {
    public static void main(String[] args) {
        
        //线程工厂用于给线程池创建的线程加上一些特征
        //你可以通过线程工厂指定线程的优先级、是否是守护线程等等
        ThreadFactory factory = new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                Thread t = new Thread(r);

                //
                t.setUncaughtExceptionHandler((Thread thread,Throwable e) -> {
                    if(e != null){
                        System.err.println(e.getMessage());
                    }
                });
                return t;
            }
        };

        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                1,
                2,
                30,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(),
                factory
        );

        executor.execute(() -> {
            //模拟业务异常
            int i = 1/0;
        });
        executor.shutdown();

    }
}

​

        原理:

        (1)ThreadFactor接口用于声明线程的属性,如线程的优先级、名称、守护进程状态等,它是线程池的构造参数之一;如果创建线程池时传入了ThreadFactor,线程池在创建线程时会按照ThreadFactor指定的形式来创建。

        (2)我们让线程调用了setUncaughtExceptionHandler()方法,这个方法需要一个参数:UncaughtExceptionHandler接口,当线程由于未捕获的异常而突然终止时,会调用这个接口的uncaughtException()方法,我们可以自定义这个方法的实现逻辑,对异常做处理。相当于线程执行任务过程中如果出现异常,那么就会回调uncaughtException()方法,如下图所示。

        如果本文对你有所帮助,不妨点个赞支持一下!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1281143.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++ regex】C++正则表达式

文章目录 前言一、正则表达式是什么&#xff1f;二、<regex>库的基础使用2.1 第一个示例2.1 <regex>库的函数详解std::regex_matchstd::regex_searchregex_search 和 regex_match 的区别std::regex_replacestd::regex_iterator 和 std::sregex_iterator&#xff1a…

未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序报错的解决办法

当在本地计算机上使用Microsoft Office相关库时&#xff0c;可能会出现“未在本地计算机上注册microsoft.ACE.oledb.12.0”提供程序的报错。这是由于缺少相关的驱动程序或者未安装相应的软件所导致的。下面是解决该问题的完整攻略。 可能是因为没有安装数据访问组件&#xff0…

LeetCode(51)简化路径【栈】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 简化路径 1.题目 给你一个字符串 path &#xff0c;表示指向某一文件或目录的 Unix 风格 绝对路径 &#xff08;以 / 开头&#xff09;&#xff0c;请你将其转化为更加简洁的规范路径。 在 Unix 风格的文件系统中&#xff…

Go 程序编译过程(基于 Go1.21)

版本说明 Go 1.21 官方文档 Go 语言官方文档详细阐述了 Go 语言编译器的具体执行过程&#xff0c;Go1.21 版本可以看这个&#xff1a;https://github.com/golang/go/tree/release-branch.go1.21/src/cmd/compile 大致过程如下&#xff1a; 解析 (cmd/compile/internal/synt…

【文献阅读笔记】基于自监督的异常检测和定位:SSM

2022 IEEE TRANSACTIONS ON MULTIMEDIA 领域&#xff1a;异常检测 目标&#xff1a;图像输入数据 文章目录 1、模型2、方法2.1、random masking2.2、restoration network2.3、损失函数2.4、推理时的渐进细化 3、实验4、引用5、想法 1、模型 训练&#xff1a; 每个图像实时生成随…

时间复杂度为O (nlogn)的排序算法

归并排序 归并排序遵循分治的思想&#xff1a;将原问题分解为几个规模较小但类似于原问题的子问题&#xff0c;递归地求解这些子问题&#xff0c;然后合并这些子问题的解来建立原问题的解&#xff0c;归并排序的步骤如下&#xff1a; 划分&#xff1a;分解待排序的 n 个元素的…

智能诊疗体验:整合AI技术的互联网医院小程序开发

在科技化的趋势下&#xff0c;互联网医院小程序的开发变得愈发重要&#xff0c;尤其是通过整合人工智能&#xff08;AI&#xff09;技术&#xff0c;进一步提升了就医的效率。 一、引言 互联网医院小程序其开发目标是提高医疗服务的效率&#xff0c;同时也也提升了用户的就医…

Linux学习笔记之七(shell脚本的基本语法)

Shell 1、Shell脚本2、常用运算符2、特殊语法4、关于变量的一些命令4.1、echo4.2、export4.3、read4.4、declare/typeset4.5、local4.6、unset 5、基本逻辑语法5.1、if判断5.2、for循环5.3、while循环5.4、case语句 6、函数定义7、多脚本链接 1、Shell脚本 学习shell脚本开发之…

Difference between getc(), getchar(), and gets()

getc(): 从输入中只能读单个字符 getchar()&#xff1a;从标准输入流中输入都单个字符。 两者基本等同&#xff0c;唯一不一样的是getc()是任何输入流&#xff0c;而getchar()是标准输入流。 gets:可以读入含有空格的字符串 // Example for getc() in C #include <stdio.h…

DDD系列 - 第4讲 从架构师的角度看待DDD - 一个关于拆解、微服务、面向对象的故事(二)

目录 第3次拆解 - 面向对象分析与设计3.1 交互入口实现层3.2 面向对象分析3.2.1 根据业务映射类3.2.2 对象持久化仓库3.2.3 自定义属性类3.2.4 类间的关联关系3.2.5 分包提升内聚、包内指定入口类降低耦合3.2.6 定义交互出口3.3 流程编排 & 业务编排3.4 交互出口实现层 &am…

使用AOS实现网页动画效果

在现代Web开发中&#xff0c;动画效果是提升用户体验和页面交互性的重要因素之一。而AOS&#xff08;Animate On Scroll&#xff09;作为一个强大的动画库&#xff0c;可以帮助我们轻松地实现网页元素的滚动动画效果。 什么是AOS&#xff1f; AOS是一个基于CSS3和JavaScript的…

Python学习路线 - Python语言基础入门 - 判断语句

Python学习路线 - Python语言基础入门 - 判断语句 前言布尔类型和比较运算符布尔类型布尔类型的定义 比较运算符 if语句的基本格式if判断语句 if else 语句if elif else 语句判断语句的嵌套实战案例 前言 进行逻辑判断&#xff0c;是生活中常见的行为。同样&#xff0c;在程序…

【uni-app】赋予你的APP(Android原生)小程序开发能力

采用DCloud(数字天堂&#xff08;北京&#xff09;网络技术有限公司)的uniMPsdk(uni小程序SDK)&#xff0c;是为原生App打造的可运行基于 uni-app 开发的小程序前端项目的框架&#xff0c;从而帮助原生App快速获取小程序的能力。 uni-app文档地址(小程序开发人员开发用) uniMP…

冗余链路和生成树协议

文章目录 冗余链路生成树协议 冗余链路 背景&#xff1a;在许多交换机或者交换机设备组成的网络环境中&#xff0c;通常都使用一些备份连接&#xff0c;来提高网络的健全。在金融网中A和B之间不止一条线路&#xff0c;保证网络的安全性能。备份连接也叫做冗余链路 冗余链路带…

Xshell会话文件解密获取密码

Xshell会话文件解密获取密码 开发了一个小工具用于获取已存储的xshell会话密码功能简介截图展示下载地址 开发了一个小工具用于获取已存储的xshell会话密码 在日常开发中&#xff0c;服务器太多&#xff0c;密码记不住。使用xshell管理服务器会话&#xff0c;记住密码&#xf…

详解递归锁,以及递归锁与其他同步机制的区别

什么是递归锁 递归锁是一种多线程同步机制&#xff0c;用于解决线程在多次获取同一个锁时产生死锁的问题。在递归锁中&#xff0c;同一个线程可以多次获取同一个锁&#xff0c;而不会造成死锁。 递归锁具有两个主要操作&#xff1a;上锁&#xff08;lock&#xff09;和解锁&a…

python 自主学习笔记

文章目录 前言相关教程模板字符串JavaScriptC#Python 临时变量C#的ValueTuplePython字典 自定义模块化封装的文件路径问题解决方案 暂时结束 前言 最近在学halcon&#xff0c;机器视觉&#xff0c;越学越发现&#xff0c;python是无法避免的语言。因为python用途实在是太广了。…

深度解析:整数和浮点数在内存中的存储

深度解析&#xff1a;整数和浮点数在内存中的存储 引言 在计算机科学中&#xff0c;理解整数和浮点数在内存中的存储方式是深入学习的关键一步。这篇博客将带你深入探讨整数和浮点数的内存表示&#xff0c;并通过代码实例详细解析其存储结构。 整数的内存存储 对于整形来说&a…

Redis 数据结构详解

分类 编程技术 Redis 数据类型分为&#xff1a;字符串类型、散列类型、列表类型、集合类型、有序集合类型。 Redis 这么火&#xff0c;它运行有多块&#xff1f;一台普通的笔记本电脑&#xff0c;可以在1秒钟内完成十万次的读写操作。 原子操作&#xff1a;最小的操作单位&a…

【开源】基于Vue+SpringBoot的音乐平台

项目编号&#xff1a; S 055 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S055&#xff0c;文末获取源码。} 项目编号&#xff1a;S055&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示 四、核心代码4.1 查询单首…