Spring线程池学习笔记
Spring提供了多种方式来配置和使用线程池,最常见的是通过
TaskExecutor和ThreadPoolTaskExecutor。
Spring线程池
TaskExecutor 接口
TaskExecutor 是Spring框架中的一个接口,它是对Java的Executor接口的简单封装。它的主要目的是为了提供一个统一的接口来执行任务。
public interface TaskExecutor extends Executor {void execute(Runnable task);
}
ThreadPoolTaskExecutor
ThreadPoolTaskExecutor 是Spring提供的一个实现类,它是对Java的ThreadPoolExecutor的封装,提供了更多的配置选项和Spring集成。
配置 ThreadPoolTaskExecutor
通过XML配置或Java配置来定义
ThreadPoolTaskExecutor。
Java配置
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;@Configuration
public class ThreadPoolConfig {@Beanpublic ThreadPoolTaskExecutor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5); // 核心线程数executor.setMaxPoolSize(10); // 最大线程数executor.setQueueCapacity(25); // 队列容量executor.setThreadNamePrefix("MyThread-"); // 线程名前缀executor.initialize();return executor;}
}
XML配置
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"><property name="corePoolSize" value="5" /><property name="maxPoolSize" value="10" /><property name="queueCapacity" value="25" /><property name="threadNamePrefix" value="MyThread-" />
</bean>
使用 ThreadPoolTaskExecutor
配置好线程池后,通过注入TaskExecutor来使用它。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;@Service
public class MyService {@Autowiredprivate ThreadPoolTaskExecutor taskExecutor;public void executeTask(Runnable task) {taskExecutor.execute(task);}
}
线程池的参数解释
- corePoolSize: 核心线程数,即使线程空闲也不会被回收。
- maxPoolSize: 最大线程数,当队列满了之后,线程池会创建新的线程,直到达到最大线程数。
- queueCapacity: 任务队列的容量,当线程数达到核心线程数时,新任务会被放入队列中等待执行。
- threadNamePrefix: 线程名前缀,方便调试和日志记录。
线程池的工作流程
- 当有任务提交时,线程池会首先尝试使用核心线程来执行任务。
- 如果核心线程都在忙,任务会被放入队列中等待。
- 如果队列满了,线程池会创建新的线程,直到达到最大线程数。
- 如果线程数达到最大线程数且队列也满了,新的任务会被拒绝
(通过设置拒绝策略来处理)。
拒绝策略
当线程池和队列都满了,新的任务会被拒绝。Spring提供了几种拒绝策略:
- AbortPolicy: 直接抛出异常(默认策略)。
- CallerRunsPolicy: 由调用线程来执行任务。
- DiscardPolicy: 直接丢弃任务。
- DiscardOldestPolicy: 丢弃队列中最旧的任务,然后尝试重新提交新任务。
通过setRejectedExecutionHandler方法来设置拒绝策略。
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 满了调用线程执行,认为重要任务
关闭线程池
在应用关闭时,确保正确关闭线程池,以释放资源。
taskExecutor.shutdown();
异步执行
Spring还提供了@Async注解来支持异步任务执行。
将方法标记为异步,Spring会自动使用配置的线程池来执行这些方法。
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;@Service
public class MyService {@Asyncpublic void asyncMethod() {// 异步执行的代码}
}
统一项目管理的线程池封装异常
优雅停机
线程池的waitForTasksToCompleteOnShutdown 的 默认参数
private boolean waitForTasksToCompleteOnShutdown = false;
Spring 的线程池为什么可以优雅停机,就是继承了DisposableBean的Destroy会被Spring回调

如何捕获线程异常
如果不处理的话
线程可以手动设置处理类

自定义未捕获异常时捕获并处理异常信息
@Slf4j
public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{@Overridepublic void uncaughtException(Thread t, Throwable e) {log.error("Exception in thread", e);}}
单个线程池测试
Thread thread = new Thread(()->{log.error("123");throw new RuntimeException("异常");});thread.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());thread.start();

项目共用线程池
自定义未捕获异常时捕获并处理异常信息
@Slf4j
public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{@Overridepublic void uncaughtException(Thread t, Throwable e) {log.error("Exception in thread", e);}}
自定义线程工厂(设计模式——装饰器)
@AllArgsConstructor
public class MyThreadFactory implements ThreadFactory {private static final MyUncaughtExceptionHandler UNCAUGHT_EXCEPTION_HANDLER = new MyUncaughtExceptionHandler();private ThreadFactory originalThreadFactory;/*** @param r a runnable to be executed by new thread instance* @description 额外装饰我们需要的线程* @return*/@Overridepublic Thread newThread(Runnable r) {Thread thread = originalThreadFactory.newThread(r);thread.setUncaughtExceptionHandler(UNCAUGHT_EXCEPTION_HANDLER);return thread;}
}
创建ThreadPoolConfig
@Configuration
@EnableAsync
public class ThreadPoolConfig implements AsyncConfigurer {/*** 项目共用线程池,用于处理核心异步任务。*/public static final String MYTHREAD_EXECUTOR= "MyThreadExecutor";/*** 配置项目共用线程池,用于处理核心业务逻辑。** 线程池配置:* - 核心线程数:10* - 最大线程数:10(固定大小线程池)* - 队列容量:200(缓冲待处理任务)* - 线程名称前缀:MyThread-executor-* - 拒绝策略:调用线程执行(保障重要任务不丢失)** @return 配置完成的线程池实例。*/@Bean(MYTHREAD_EXECUTOR)@Primarypublic ThreadPoolTaskExecutor mallchatExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(10);executor.setMaxPoolSize(10);executor.setQueueCapacity(200);executor.setThreadNamePrefix("MyThread-executor-");executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());executor.setThreadFactory(new MyThreadFactory(executor));executor.initialize();return executor;}
}
测试
@Autowiredprivate ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Testpublic void thread2(){threadPoolTaskExecutor.execute(()->{log.error("123");throw new RuntimeException("异常");});}

总结
Spring中的线程池配置和使用非常灵活,能够满足大多数并发任务的需求。通过合理配置线程池参数,有效地管理资源,提高应用的并发处理能力。
相关文章:
Spring线程池学习笔记
Spring提供了多种方式来配置和使用线程池,最常见的是通过TaskExecutor和ThreadPoolTaskExecutor。 Spring线程池 TaskExecutor 接口 TaskExecutor 是Spring框架中的一个接口,它是对Java的Executor接口的简单封装。它的主要目的是为了提供一个统一的接口…...
ArcGIS操作:08 计算shp面积并添加到属性表
1、打开属性表 注意:计算面积前,需要把shp的坐标系转化为投影坐标系(地理坐标系用于定位、投影坐标系用于测量) 2、创建字段 3、编辑字段名、类型 4、选择字段,计算几何 5、选择属性、坐标系、单位...
安卓音频框架混音器
在 Android 音频框架中,混音器(Mixer) 是 AudioFlinger 服务的核心组件之一,负责将多个音频流(来自不同应用或系统组件)混合为统一的输出流,再传输到音频硬件设备(如扬声器、耳机等&…...
左值引用与指针的区别
很多朋友遇到过这个问题:左值引用与指针有哪些区别?脑子里闪过很多答案,但大部分都是各自的定义,真要说他们两个有什么区别,有的时候还这是说不上来。本文针对这个问题进行归纳总结,希望对大家有所帮助。 …...
Linux基础使用和程序部署
目录 1.Linux 1.2 Linux的环境搭配 1.2.1 使用云服务器 1.2.2使用终端软件连接到Linux 1.3. Linux 常用命令 1. ls:列出当前目录中的文件和子目 2.pwd:显示当前工作目录的路径 3.cd:改变工作目录,将当前的工作目录改变到指定目…...
Linux驱动开发之串口驱动移植
原理图 从上图可以看到RS232的串口接的是UART3,接下来我们需要使能UART3的收发功能。一般串口的驱动程序在内核中都有包含,我们配置使能适配即可。 设备树 复用功能配置 查看6ull如何进行uart3的串口复用配置: 设备树下添加uart3的串口复用…...
计算机毕业设计SpringBoot+Vue.js美食推荐系统商城(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
指针小节.
....指针的第四个作用:函数的结果和计算状态分开 高级指针。。 指针中的数据类型:获取字节数据的个数。步长:指针移动一次的字节个数(int,long。。。各自字节都不同) 加减都可以...
[Qt5] QJson数据之间的转换以及QByteArray图像数据压缩
📢博客主页:https://loewen.blog.csdn.net📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!📢本文由 丶布布原创,首发于 CSDN,转载注明出处🙉📢现…...
2025年能源工作指导意见
2025年是“十四五”规划收官之年,做好全年能源工作意义重大。为深入贯彻落实党中央、国务院决策部署,以能源高质量发展和高水平安全助力我国经济持续回升向好,满足人民群众日益增长的美好生活用能需求,制定本意见。 一、总体要求…...
Android 获取jks的SHA1值:java.io.IOException: Invalid keystore format
命令生成 keytool -list -v -keystore 全路径.jks -alias 别名 -storepass 密码 -keypass 密码 1、遇到 的问题: 通过快捷键 ‘win r’ 启动的小黑框运行上面的命令会出现下面这个错误keytool 错误: java.io.IOException: Invalid keystore format 2、解决问题 …...
深入探索像ChatGPT这样的大语言模型-02-POST training supervised finetuning
参考 【必看珍藏】2月6日,安德烈卡帕西最新AI普及课:深入探索像ChatGPT这样的大语言模型|Andrej Karpathy fineweb知乎翻译介绍 fineweb-v1原始连接 fineweb中文翻译版本 Chinese Fineweb Edu数据集 查看网络的内部结果,可以参…...
广义线性模型下的数据分析(R语言)
一、实验目的: 通过上机试验,掌握利用R实现线性回归分析、逻辑回归、列联分析及方差分析,并能对分析结果进行解读。 数据: 链接: https://pan.baidu.com/s/1JqZ_KbZJEk-pqSUWKwOFEw 提取码: hxts 二、实验内容: 1、2…...
AutoMQ:无需 Cruise Control 实现 Kafka 的自动分区再平衡
导读:AutoMQ是一款贯彻云优先理念来设计的 Kafka 替代产品。AutoMQ 创新地对 Apache Kafka 的存储层进行了基于云的重新设计,在 100% 兼容 Kafka 的基础上通过将持久性分离至 EBS 和 S3 带来了 10x 的成本降低以及 100x 的弹性能力提升,并且相…...
在剪映中给英文学习视频添加中文字幕
文章目录 一、剪映是什么?二、使用步骤1.下载2.操作 一、剪映是什么? 剪映是由字节跳动公司开发的一款功能强大且易于使用的视频编辑软件,在移动端和电脑端均有应用。 二、使用步骤 1.下载 2.操作...
Opencv之sift特征检测和FLANN 匹配器进行指纹特征匹配
sift特征检测和FLANN 匹配器进行指纹匹配 目录 sift特征检测和FLANN 匹配器进行指纹匹配1 sift特征检测1.1 概念1.2 优缺点 2 FLANN 匹配器2.1 概念2.2 工作原理与匹配方式2.3 FLANN 匹配器的使用步骤2.4 优缺点 3 函数3.1 特征检测匹配3.2 匹配符合条件点并绘制 3 代码测试3.1…...
rust学习~tokio的io
await Suspend execution until the result of a Future is ready. 暂停执行,直到一个 Future 的结果就绪。 .awaiting a future will suspend the current function’s execution until the executor has run the future to completion. 对一个 Future 使用 .awa…...
FPGA开发,使用Deepseek V3还是R1(2):V3和R1的区别
以下都是Deepseek生成的答案 FPGA开发,使用Deepseek V3还是R1(1):应用场景 FPGA开发,使用Deepseek V3还是R1(2):V3和R1的区别 FPGA开发,使用Deepseek V3还是R1&#x…...
本地部署大数据集群前置准备
1. 设置VMware网段 虚拟网络编辑器——更改设置——选择VMnet8——子网改成192.168.88.0——NAT设置——网关设置为192.168.88.2 2. 下载CentOS操作系统 下载CentOS 7.6(1810)版本 3. 在VMware中安装CentOS操作系统 创建新的虚拟机——典型——安装光盘映像文件——输入账…...
Spring Boot整合RabbitMQ
1. 环境准备 Spring Boot 2.1.3.RELEASERabbitMQ 3.xJDK 8 或以上Maven 3.5 2. 安装Erlang、RabbitMQ 2.1 安装前准备 RabbitMQ 依赖 Erlang 环境,需确保两者的版本匹配,官方兼容性参考:RabbitMQ & Erlang 版本对照表。 2.2 下载安…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...

