Spring异步线程池的问题

今天看一视频,提到说 Spring默认的异步线程池比较简单,每次执行异步任务,都会新建一个线程进行处理,不会重复利用,所以在用Spring框架开发的时候,需要自定义异步线程池。第一次听到这个说法。遂开始百度。

百度 “Spring 默认的异步线程池的配置”

不到三秒看到了这么一个博客: https://www.cnblogs.com/zhaoyuan72/p/16347289.html

看到了 原文地址是从知乎来的,遂跳转到知乎:https://zhuanlan.zhihu.com/p/346086161。

我这个人有个毛病,干什么都想看到最原始的那个东西,比如听歌就要听原唱,不听改编翻唱,好吧,其实这样没必要。

作者开篇提到

上一篇分享了JDK自带的线程池 ThreadPoolExecutor 的配置和参数详解,然而我们实际开发中更多的是使用SpringBoot来开发,Spring默认也是自带了一个线程池方便我们开发,它就是ThreadPoolTaskExecutor,接下来我们就来聊聊Spring的线程池吧。

就是说 JDK自带的线程池是 ThreadPoolExecutor,而Spring框架又自我封装了一个线程池 ThreadPoolTaskExecutor。说实话,这个思想就是这样,JDK本身有自带的东西,很多框架觉得JDK的东西不好,都会自己二次改造,再来一个。

比如说JDK默认的序列化机制速度慢,生成的字节占用空间大,用的是java.io.ObjectInputStream 和 ObjectOutputStream。所以一般我们也不会用JDK的序列化机制,比如前后端交互我们用JSON,JSON又可以用FastJson或者Jackson等等。其他的场景如一个RPC框架我们可以用 Java 下面的最快的序列化工具 Kyro。(举例可能不恰当,但是就是这么个意思)

再比如说 Spring也有些东西,可能其他框架觉得它不太好,也会自己写一个。比如 StringUtils 这个类,一般开发中可能都会用 common.lang3的StringUtils,MP也会封装自己的 StringUtils,Hutool也会封装自己的StringUtils。

突然就理解了 common.lang 和 common.lang3 以及 fastjson 和fastjson2 的关系了。
commons.lang3 就是 common.lang 的3.x版本, 但是应该是一次大版本升级,所以重新搞成了一个artifact,fastjson2也是如此。
common.lang3的一个版本一定是从3.x开始的。fastjson2也一定是从2.x开始的

我们大致看一下 ThreadPoolExecutor。
参考了这篇文章。
https://blog.csdn.net/cy973071263/article/details/131484311 。

大致看完这个,开始看Spring的 ThreadPoolTaskExecutor。就看之前知乎的那一篇文章,作者先说的是 SimpleAsyncTaskExecutor,

在这里插入图片描述

在这里插入图片描述

于是我决定执行自己的demo

在这里插入图片描述

发现几个问题
1.没有如作者博客一样,我的demo线程复用了,没有一直创建,但是默认好像是8个线程
2.没有如博客作者一样打印出来 SimpleAsyncTaskExecutor 这个类

于是,去看了一下博客的日期,距今(2024年0925日)已经三年多了,Spring我目前用的都是5.3的版本了

在这里插入图片描述
看到了这个,可以去翻源码了,猜想是不是新版本Spring 默认的 concurrencyLimit 是8

在这里插入图片描述

看源码,全局搜 concurrencyLimit。

在这里插入图片描述
卧槽,那岂不是沙雕了。

又看一下我之前设置 的定时默认线程数是 8,但是我已经全部注释掉了呀
在这里插入图片描述

于是,开始去找新的博客看看。这次搜索的词条是:

Spring默认的异常线程池 SimpleAsyncTaskExecutor
并刻意去看2023、2024年的帖子,发现基本都说 默认的异步线程池 SimpleAsyncTaskExecutor 线程确实不可以重用。
感觉还是我本身项目代码的问题,我应该在某个地方设置了 最多可用线程数为8或者怎么样。

尝试1:既然注释没有效果,直接删掉 SchedulingConfig 这个类
发现还是一样的。

尝试2:去其他项目,运行这个demo
发现还是一样的 8 个线程在重用

则现在又有1种猜测
我加了 @Async 注解,到底有没有用 SimpleAsyncTaskExecutor 线程池

突然想起来了之前看 一个项目做的笔记。
说 @Async 注解的原理是

在这里插入图片描述
发现这里的 核心线程数确实是8 ,md破案了。
感觉根本没有用 SimpleAsyncTaskExecutor。

再去问 文心一言

当在Spring应用中使用@Async注解来声明异步方法时,如果没有明确指定线程池,那么默认情况下会使用SimpleAsyncTaskExecutor ,那如果是SpringBoot应用呢

在Spring Boot应用中,当使用@Async注解来声明异步方法时,如果没有明确指定线程池,其默认行为会根据Spring Boot的版本有所不同。

早期版本

在Spring Boot的某些早期版本中(通常指2.1之前的版本),如果没有特别配置,@Async注解标注的异步方法可能会默认使用SimpleAsyncTaskExecutor。这个执行器每次执行一个任务时都会创建一个新的线程,而不是复用现有的线程,这可能导致在高并发场景下创建大量线程,进而引发性能问题。

2.1及以后版本

从Spring Boot 2.1版本开始,情况发生了变化。在Spring Boot 2.1及以后的版本中,@Async注解默认使用的线程池不再是SimpleAsyncTaskExecutor,而是ThreadPoolTaskExecutor。这意味着,如果没有特别配置,异步方法将会在一个线程池中执行,该线程池具有核心线程数、最大线程数、队列容量等配置参数。

具体来说,ThreadPoolTaskExecutor的默认配置通常包括:

  • 核心线程数:8
  • 最大线程数Integer.MAX_VALUE
  • 队列容量Integer.MAX_VALUE(使用LinkedBlockingQueue
  • 空闲线程保留时间:60秒
  • 线程池拒绝策略AbortPolicy(当线程池饱和时,尝试执行新任务会抛出异常)

自定义配置

尽管Spring Boot提供了默认的线程池配置,但在实际应用中,根据业务需求和系统负载,这些默认配置可能需要调整。开发者可以通过在application.ymlapplication.properties文件中添加相应的配置属性来自定义线程池的行为。

例如,要调整核心线程数、最大线程数和队列容量,可以在application.properties中添加如下配置:

spring.task.execution.pool.core-size=10
spring.task.execution.pool.max-size=20
spring.task.execution.pool.queue-capacity=50

或者,在application.yml中添加类似配置:

spring:task:execution:pool:core-size: 10max-size: 20queue-capacity: 50

结论

因此,在Spring Boot应用中,如果没有明确指定线程池,@Async注解默认使用的线程池从Spring Boot 2.1版本开始是ThreadPoolTaskExecutor,而不是SimpleAsyncTaskExecutor。这提供了更好的线程复用和资源管理能力,但在实际应用中仍需要根据需要进行适当的配置调整。

再点进去

在这里插入图片描述

在这里插入图片描述

确实需要自定义异步线程池。

我之前的demo默认走的是 ThreadPoolTaskExecutor的配置。

但是这里我就好奇了,那在Spring 框架里面默认的线程池配置是通过哪个类实现的???

在这里插入图片描述

在这里插入图片描述

ai得出这个答案,我就不单独去验证Spring框架下面,@Scheduled 注解的行为了,毕竟现在都是基于SpringBoot开发。

如何自定义异步线程池,参考了 https://blog.csdn.net/kdzandlbj/article/details/139046266 的第二种方式。

在这里插入图片描述

异步线程池定义如图所示

在这里插入图片描述

启动项目,发现确实生效了,最大的执行线程就是5

在这里插入图片描述

但是这里有个问题,为什么 springBoot(这应该是SpringBoot决定的吧)的log打印,好像是打印 线程名.subtring(str.length-15)

在这里插入图片描述
稍等讨论这个问题,我想知道这个

executor.setThreadNamePrefix("AsyncThreadPool-t-");

线程工厂是如何把这个 线程名前缀加在线程上的.
首先要认知到一个问题,任何框架的线程池肯定都是基于JDK线程池的,而JDK线程池里面的线程都是由线程工厂创建的 也就是 ThreadFactory。所以,直接去找线程工厂。

在这里插入图片描述

在这里插入图片描述
点进去 CustomizableThreadFactory 看一看

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

再来说 SpringBoot输出的为什么是 substring的ThreadName。

在这里插入图片描述
找了一下感觉乱七八糟的,没什么章法,直接百度吧。

百度了一圈没有说什么源码的,都是说配置的,没劲,我自己debug看吧。

在这里插入图片描述

在这里插入图片描述

但是代码到下面就走完了。

在这里插入图片描述

事前先百度了一下。
在这里插入图片描述

ok,到这里 线程日志打印截断15个字符就结束了。

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

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

相关文章

Word页眉内容自动填充为章节标题

Word页眉内容自动填充为章节标题 在写毕业论文的过程中,通常要求将页眉设置为章节标题,例如这样 通常,页眉内容我们都是手敲上去的,其实在Word中可以设置为自动引用章节标题,以下为设置方法,仅供参考&…

JVM错误:OutOfMemoryError: GC overhead limit exceeded

OutOfMemoryError: GC overhead limit exceeded 在Window服务器上跑一个项目,无意中出现服务访问不了,查看日志文档,第一次遇到了这个异常信息。 1. 错误含义 OutOfMemoryError: GC overhead limit exceeded 是 JVM 中的一种错误&#xff…

jmeter入门:脚本录制

1.设置代理。 网络连接-》代理-》手动设置代理. ip: 127.0.0.1, port:8888 2. add thread group 3. add HTTP(s) test script recorder, target controller chooses Test plan-> thread Group 4. click start. then open the browser …

鸡兔同笼,但是线性代数

灵感来自:bilibili,巨佬! 我们有 14 14 14 个头, 32 32 32 只脚,所有鸡和兔都没有变异,头和脚都完整,没有数错。还有什么 Bug 吗 小学奥数 假设全是鸡,则有 14 2 28 14 \time…

【2024保研经验帖】东南大学计算机学院夏令营

前言 背景:末211,专业计算机科学与技术,rk前5%,无科研,只有几个竞赛 东南大学计算机学院夏令营需要老师推荐,一个老师的推荐名额感觉应该挺多的,因为学硕和专硕都进了两百多人,总共…

利用 Python 爬虫采集 1688商品详情

1688是中国的一个大型B2B电子商务平台,主要用于批发和采购各种商品。对于需要从1688上获取商品详情数据、工程数据或店铺数据的用户来说,可以采用以下几种常见的方法: 官方API接口:如果1688提供了官方的API接口,那么可…

猎板PCB设计中的HDI板技术革新与实践

在设计工业控制器的HDI板时,需要注意以下几个关键方面: 布线设计:由于HDI板布线密度高,合理规划走线非常关键,避免交叉和重叠,确保信号传输的稳定性和可靠性。需要控制线宽和线距,根据电路板的…

docker的安装与启动——配置国内Docker源

移除旧版本docker sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine 配置docker yum源。 sudo yum install -y yum-utils sudo yum-config-manager –add-repo ht…

SAP_FI_表ACDOCA取代的表

在 SAP S/4HANA 系统中,ACDOCA(通用分录表,Universal Journal)引入了全新的数据结构,取代了原先 ERP 系统中多个财务和控制模块的表。ACDOCA 通过一个单一表格整合了财务会计(FI)和管理会计&…

C语言 | Leetcode C语言题解之第454题四数相加II

题目&#xff1a; 题解&#xff1a; struct hashTable {int key;int val;UT_hash_handle hh; };int fourSumCount(int* A, int ASize, int* B, int BSize, int* C, int CSize, int* D, int DSize) {struct hashTable* hashtable NULL;for (int i 0; i < ASize; i) {for (…

日语学习零基础生活日语口语柯桥外语学校|股票用日语怎么说?

在日语中&#xff0c;“股票”可以说&#xff1a; • 株&#xff08;かぶ&#xff09; 这是最常用的表达方式&#xff0c;直接表示“股票”。 例如&#xff1a; 株を買う - 买股票 株を売る - 卖股票 • 株式&#xff08;かぶしき&#xff09; 这个词也是“股票”的意…

模拟实现消息队列(基于SpringBoot实现)

项目代码 提要&#xff1a;此处的消息队列是仿照RabbitMQ实现&#xff08;参数之类的&#xff09;&#xff0c;实现一些基本的操作&#xff1a;创建/销毁交互机&#xff08;exchangeDeclare&#xff0c;exchangeDelete&#xff09;&#xff0c;队列&#xff08;queueDeclare&a…

【CF2021E】Digital Village(All Version)

题目 给你一张 n n n 个点 m m m 条边的无向图&#xff0c;有 p p p 个关键点。你需要选择 k k k 个点染黑&#xff0c;使得这 p p p 个关键点到这 k k k 个黑点的代价和最小。定义代价为两点之间边权最大的边的最小值。 你需要求出 k 1,2,…,n 的所有答案 E1 n,m,p&l…

前端页面模块修改成可动态生成数据模块——大部分数据为GPT生成(仅供学习参考)

前端页面模块修改成可动态生成数据模块&#xff1a; 这些案例展示了如何通过Blade模板将前端页面模块变成可动态生成的模板。通过巧妙使用Blade语法、控制结构、CSS/JS分离、组件复用等技巧&#xff0c;可以大大提高代码的灵活性和复用性。在Laravel的Controller中准备好数据并…

QT-多线程、线程池的使用

在进行桌面应用程序开发的时候&#xff0c; 假设应用程序在某些情况下需要处理比较复杂的逻辑&#xff0c;如果只有一个线程去处理&#xff0c;就会导致窗口卡顿&#xff0c;无法处理用户的相关操作。这种情况下就需要使用多线程&#xff0c;其中一个线程处理窗口事件&#xff…

WPS的JS宏实现删除某级标题下的所有内容

想要删除Word文档中&#xff0c;包含特定描述的标题下所有内容&#xff08;包含各级子标题以及正文描述&#xff09;。 例如下图中&#xff0c;想删除1.2.1.19.1业务场景下所有内容&#xff1a; 简单版&#xff1a; 删除光标停留位置的大纲级别下所有的内容。实现的JS代码如下…

在 ubantu 20.04 云服务器上基于 bochs 编译 linux0.11

安装 bochs 将下面的命令全部执行一遍&#xff1a; sudo apt-get install build-essential sudo apt-get install xorg-dev sudo apt-get install bison sudo apt-get install g 我们区官网下载一下bochs的源码&#xff1a;bochs下载 这里我下载好了bochs2.6.8 这个版本的…

【SQL】DDL语句

文章目录 1.SQL通用语法2.SQL的分类3.DDL3.1数据库操作3.2 表操作3.2.1 表操作--数据类型3.2.2 表操作--修改3.2.3 表操作--删除 SQL 全称 Structured Query Language&#xff0c;结构化查询语言。操作关系型数据库的编程语言&#xff0c;定义了一套操作关系型数据库统一标准 。…

Could not get JDBC Connection: wait millis 10000, active 500

Could not get JDBC Connection: nested exception is com,alibaba,druid.pool,GetConnectionTimeoutException: wait millis 10000, active 500 1、生产突然出现这样的问题&#xff0c;后经过各种分析查找 jmap -dump:formatb,filewar_l.hporf 10333 ‌jmap -dumpb命令用于生成…

【大模型开发】AI提示词框架:解锁ICIO、CRISPE、BROKE和RASCEF的强大潜力

作为一名经验丰富的程序员,您是否曾感到在与AI助手交互时难以获得理想的输出?本文将为从事AI开发或经常使用AI工具的技术人员介绍四个强大的AI提示词框架:ICIO、CRISPE、BROKE和RASCEF。这些框架能帮助您更有效地与AI模型沟通,提高工作效率。 1. ICIO框架:简洁而有力 IC…