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中可以设置为自动引用章节标题,以下为设置方法,仅供参考&…

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 …

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

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

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

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

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…

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命令用于生成…

vos3000外呼系统音质不好怎么解决

音质好坏主要取决于传输网络和经由设备的处理能力 如果 VOS 没有开启媒体转发的情况下&#xff0c;出现音质不好&#xff0c;那么排查问题时完全可以认为 VOS 是正常的&#xff0c;因为VOS没有参与语音流的处理&#xff0c;所以不涉及音质问题。可以尝试以下几个解决方案&…

OSPF的不规则区域

1.远离骨干非骨干区域 2.不连续骨干 解决方案 tunnel ---点到点GRE 在合法与非ABR间建立隧道&#xff0c;然后将其宣告于OSPF协议中&#xff1b; 缺点&#xff1a;1、周期和触发信息对中间穿越区域造成资源占用&#xff08;当同一条路由来自不同区域&#xff0c;路由器会先…

nacos源码修改持久化到postgreSQL数据库

很多业务场景&#xff0c;业务功能必须用pg数据库&#xff0c;这时候注册中心如果用mysql的话&#xff0c;显得浪费资源&#xff0c;基于此&#xff0c;nacos源码修改持久化到postgreSQL数据库是一个必然需求&#xff0c;此处我们修改为只支持pg数据库&#xff0c;2.4版本的源码…

Java基础:字符串详解

1 深入解读String类源码 1.1 String类的声明 public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence { }String类是final的&#xff0c;意味着它不能被子类继承&#xff1b;String 类实现了Serializable接口&#xff0c;意味着…

界星空科技漆包线行业称重系统

万界星空科技为漆包线行业提供的称重系统是其MES制造执行系统解决方案中的一个重要组成部分。以下是对该系统的详细介绍&#xff1a; 一、系统概述 万界星空科技漆包线行业称重系统&#xff0c;是集成在MES系统中的一个功能模块&#xff0c;专门用于漆包线生产过程中的重量检…

LabVIEW惯性导航系统仿真平台

LabVIEW开发捷联惯性导航系统仿真平台&#xff0c;采用模块化设计&#xff0c;利用LabVIEW的图形化编程特性&#xff0c;提高了系统仿真的效率和精度&#xff0c;同时具备良好的可扩展性和用户交互性。 项目背景 当前&#xff0c;惯性导航系统&#xff08;INS&#xff09;的研…

【深度学习基础模型】液态状态机(Liquid State Machines, LSM)详细理解并附实现代码。

【深度学习基础模型】液态状态机&#xff08;Liquid State Machines, LSM&#xff09;详细理解并附实现代码。 【深度学习基础模型】液态状态机&#xff08;Liquid State Machines, LSM&#xff09;详细理解并附实现代码。 文章目录 【深度学习基础模型】液态状态机&#xff0…

嵌入式硬件设计知识详解

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…