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 下载安…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...

莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...

Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...

java高级——高阶函数、如何定义一个函数式接口类似stream流的filter
java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用(Math::max) 2 函数接口…...

深入解析光敏传感技术:嵌入式仿真平台如何重塑电子工程教学
一、光敏传感技术的物理本质与系统级实现挑战 光敏电阻作为经典的光电传感器件,其工作原理根植于半导体材料的光电导效应。当入射光子能量超过材料带隙宽度时,价带电子受激发跃迁至导带,形成电子-空穴对,导致材料电导率显著提升。…...