关于ThreadPoolTaskExecutor线程池的配置

news2024/11/24 18:28:50

说明:
1、线程池分类、其他

1.1、分类
IO密集型 和 CPU密集型 任务的特点不同,因此针对不同类型的任务,选择不同类型的线程池可以获得更好的性能表现。

1.1. IO密集型任务

​ IO密集型任务的特点是需要频繁读写磁盘、网络或者其他IO资源,执行时间长,CPU占用率较低。

对于这类任务,线程的执行时间主要取决于IO操作的速度,而非CPU的执行能力。

​ 因此,线程池的线程数应该设置较大,以便充分利用IO资源。

通常建议使用CachedThreadPool线程池或者FixedThreadPool线程池来处理IO密集型任务。

1.2. CPU密集型任务

​ CPU密集型任务的特点是需要进行大量的计算,执行时间长,CPU占用率较高。

对于这类任务,线程的执行时间主要取决于CPU的执行能力。

​ 因此,线程池的线程数应该设置较小,以充分利用CPU的计算能力,避免过多的线程切换和上下文切换导致的性能损失。

通常建议使用FixedThreadPool线程池或者SingleThreadPool线程池来处理CPU密集型任务。

1.2. 异步线程池的选择
对于异步线程池,通常建议使用IO密集型线程池。
异步任务通常是网络IO或磁盘IO等操作,这些操作的执行时间相对于CPU计算的执行时间要长得多。
使用IO密集型线程池可以更好地利用IO资源,提高多个异步任务的执行效率和吞吐量,
同时避免由于过多的线程切换和上下文切换导致的性能损失。

1.3. 线程池工作步奏
很多任务——》线程池创建核心线程——》任务超过最大线程——》把任务放入队列中等待执行——》队列中放满了——》进入处理策略

/**
 * @Description: 线程池配置
 */
@Configuration
@EnableAsync
public class ThreadPoolConfig {

	/**
	 * 打印日志
	 */
	private Logger logger = LoggerFactory.getLogger(getClass());

	/**
	 * cpu 核心数量
	 */
	public static final int cpuNum = Runtime.getRuntime().availableProcessors();

	/**
	 * 线程池配置
	 *
	 * @return
	 */
	@Bean("taskExecutor")
	public TaskExecutor taskExecutor() {
		ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
		// 核心线程数:当线程池中的线程数量为 corePoolSize 时,即使这些线程处于空闲状态,也不会销毁(除非设置 allowCoreThreadTimeOut=true)。
		// -> 核心线程,也就是正在处理中的任务
		// -> 虽然 CPU 核心数可以作为线程池中线程数量的参考指标,但最终线程数量还需要根据具体情况进行设置和调整。
		// -> 如果同时运行的线程数量超过 CPU 核心数,就会发生--线程上下文切换--,导致额外的开销和性能下降。所以线程不能创建得过多
		taskExecutor.setCorePoolSize(cpuNum);
		//  IO密级 :2 * N   CPU密级:1 + N
		//  最大线程数:线程池中允许的线程数量的最大值。
		//-> 当线程数 = maxPoolSize最大线程数时,还有新任务,就会放进队列中等待执行 ↓↓↓
		taskExecutor.setMaxPoolSize(2 * cpuNum);
		// 队列长度:当核心线程数达到最大时,新任务会放在队列中排队等待执行
		// -> 根据业务配置,如果队列长度过大,可能会导致系统内存资源占用过高,最终导致 OOM,需要注意控制
		// -> 如果需要执行的任务装满了队列,就会走拒绝策略 ↓↓↓
		taskExecutor.setQueueCapacity(500);
		// 当前线程池的等待时间:指等待所有任务执行完毕后线程池的最长时间。300秒 = 5分钟
		// -> 当所有任务执行完毕后,线程池会等待一段时间(即等待时间),来确保所有任务都已经完成。
		// -> 如果在等待时间内所有任务仍未完成,则线程池会强制停止,以确保任务不会无限制地执行下去。
		taskExecutor.setAwaitTerminationSeconds(300);
		//空闲线程存活时间(默认60s):设置当前线程池中空闲线程的存活时间,即线程池中的线程如果有一段时间没有任务可执行,则会被回收掉。
		// -> 当线程池中的线程数大于 corePoolSize 时,多余的空闲线程将在销毁之前等待新任务的最长时间。
		// -> 如果一个线程在空闲时间超过了 keepAliveSeconds,且当前线程池中线程数量大于 corePoolSize,则该线程将会被回收;
		// -> 核心线程会一直存活,除非线程池被关闭 或 设置下面的参数
		// -> 如果 AllowCoreThreadTimeout设置为true,核心线程也会被回收,直到线程池中的线程数降为 0。
		// 但如果线程池中有任务在执行,那么空闲线程就会一直保持存活状态,直到任务执行完毕。
		// -> 该方法的使用可以将线程池的空闲线程回收,以减少资源占用,同时也能保证线程池中始终有可用的线程来执行任务,提高线程池的效率。
		taskExecutor.setKeepAliveSeconds(60);
		// 当前线程池是否在关闭时等待所有任务执行完成
		//-> 可以确保所有任务都执行完毕后才关闭线程池,避免任务被丢弃,同时也确保线程池可以正常结束,释放资源。
		//-> 为 true 时,线程池在关闭时会等待所有任务都执行完成后再关闭
		//-> 为 false 时,线程池会直接关闭,未执行完成的任务将被丢弃。
		taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
		// 是否禁止线程池自动终止空闲的核心线程。
		// 为 true 时,空闲的核心线程会在 keepAliveTime 时间后被回收,并且在后续任务到来时需要重新创建线程来执行任务。
		// 为 false 时,线程池中的核心线程不会被回收,即使它们处于空闲状态一段时间。
		// -> 在线程池创建时,就会预先创建核心线程数的线程,这些线程将一直存在,除非线程池被关闭或重新配置。
		taskExecutor.setAllowCoreThreadTimeOut(true);
		//设置拒绝处理的策略(当线程池无法处理新的任务时,该执行什么策略)
		//new ThreadPoolExecutor.CallerRunsPolicy() 该策略为选择调用者线程进行处理
		//new ThreadPoolExecutor.AbortPolicy() 该策略为丢弃任务并抛出RejectedExecutionException异常(不设置时默认此策略)
		//new ThreadPoolExecutor.DiscardPolicy() 该策略为丢弃任务,但是不抛异常
		//new ThreadPoolExecutor.DiscardOldestPolicy() 该策略为丢弃队列最前面的任务,然后重新尝试执行任务
		taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
		// 线程池名称前缀
		taskExecutor.setThreadNamePrefix("thread-pool-");
		// 线程池初始化
		taskExecutor.initialize();
		logger.info("线程池初始化......");
		return taskExecutor;
	}

	//使用方法
	//private final TaskExecutor taskExecutor;
	//taskExecutor.execute(() -> doYourMethod());

}

在这里插入图片描述

测试500并发最大没有超过30,线程池生效
在这里插入图片描述

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

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

相关文章

Netty—Channel

文章目录 一、Channel 是什么?🤔️二、 Channel 的继承体系👪三、Channel 的初始化过程 🔍首先,channel() 指定 ChannelFactory 类型其次,Channel 实例化 一、Channel 是什么?🤔️ …

初识Java 5-1 实现隐藏

目录 库单元:package 代码组织 独一无二的包名 Java访问权限修饰符 包访问权限 接口访问权限(public) 不可访问(private) 继承访问权限(protected) 包访问权限与公共构造器 接口与实现…

基于Java+SpringBoot+Vue前后端分离医疗挂号管理系统设计和实现

博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专…

pdf怎么转cad?几个简单方法分享给你

pdf怎么转cad?PDF文件转换为CAD文件是一项非常重要的任务,特别是对于那些需要进行工程、建筑和设计的专业人士来说。在过去,这项任务可能需要耗费大量时间和精力,但现在,随着技术的不断发展,已经有很多工具…

华为云云服务器评测| 之性能测试

文章目录 前言软件安装扩展知识 收集服务器负载信息指令解析开始压测后台运行 stress 运行 sysbench 测试网络带宽总结 测试磁盘 I/O 性能I/O 性能评估总结 前言 在当今数字化时代,云计算作为一种高效、灵活的计算方式,正日益受到企业和个人用户的广泛关…

如何远程访问Linux MeterSphere一站式开源持续测试平台

文章目录 前言1. 安装MeterSphere2. 本地访问MeterSphere3. 安装 cpolar内网穿透软件4. 配置MeterSphere公网访问地址5. 公网远程访问MeterSphere6. 固定MeterSphere公网地址 前言 MeterSphere 是一站式开源持续测试平台, 涵盖测试跟踪、接口测试、UI 测试和性能测试等功能&am…

基于Java+SpringBoot+Vue前后端分离校园商铺管理系统设计和实现

博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专…

LeetCode 15 三数之和

题目链接 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 题目解析 // 1. 排序双指针 // 2. 固定一个值nums[i] 然后去剩下的位置去找 两数之和符合nums[j]nums[k]是否等于-nums[i] // 3. 细节问题:由于题目中是不可以包含重复的三元组的…

功率放大器的功能是什么功能

功率放大器是一种电子设备,用于放大输入信号的功率,并输出对应增强后的信号。功率放大器的功能主要包括增强信号的功率、保持信号的形状和质量、提供足够的电流和电压驱动负载,以满足不同应用需求。 功率放大器的主要功能是增强信号的功率。输…

阿里巴巴API接口解析,实现按关键字搜索商品

要解析阿里巴巴API接口并实现按关键字搜索商品,你需要进行以下步骤: 了解阿里巴巴API接口文档:访问阿里巴巴开放平台,找到API文档,了解阿里巴巴提供的API接口以及相关的参数、返回值等信息。注册开发者账号&#xff1…

远传水表和流量计的区别

远传水表和流量计是两种用于测量和控制水流的设备,虽然在某些方面有重叠的功能,但它们之间也有一些区别。下面我们将详细介绍这两种设备的区别。 一、定义和作用 远传水表是一种能够远程传输用水数据的水表,可以通过无线通信技术将数据传输到…

轻松解决Idea中maven无法下载源码

今天在解决问题的时候想要下载源码,突然发现idea无法下载,这是真的蛋疼,没办法查看原因,最后发现问题的原因居然是因为Maven,由于我使用的idea的内置的Bundle3的Maven,之前没有研究过本地安装和内置的区别&…

前端面试0906

// 请给出输出结果 function foo(){ console.log(a); } function bar(){ var a 3; console.log(this.a); foo(); } var a 2; bar(); 2 2 // 请从下面的问题中挑选3道进行回答 1. 防抖和节流分别是什么,一般用在什么场景? 防抖(Debounc…

CocosCreator3.8研究笔记(七)CocosCreator 节点和组件的介绍

相信很多新手朋友,肯定会问,CocosCreator 中什么是节点?什么是组件? 一、什么是组件(Component)? Cocos Creator 3.8 的工作流程是以组件式开发为核心,即以组合而非继承的方式进行游…

安卓手机记事本数据转移到苹果手机上怎么操作?

国内有不少网友使用的手机都是小米、荣耀、OPPO、vivo等安卓手机,而再次更换手机时,就想要尝试一下不同的操作系统,例如更换一台苹果手机。不过在换手机之前,还有一件重要的事情需要去做,这就是安卓手机记事本数据转移…

RS485转0_20mA输出模块设计

文章目录 1. 简介2. 功能实现3. 测试4. 开源地址 1. 简介 结合以前发的文章,我们知道,模拟量输出有两种,一种是共地型,一种是共源型。 今天开源一款rs485隔离的转0-20ma输出模块的设计。 我设计模块的原因是为了测试公司的一款…

redis实战-redis实现分布式锁redisson快速入门

前言 集群环境下的并发问题 分布式锁 定义 需要满足的条件 常见的分布式锁 redis实现分布式锁 核心思路 代码实现 误删情况 逻辑说明 解决方案 代码实现 更为极端的误删情况 Lua脚本解决原子性问题 分布式锁-redission redisson的概念 快速入门 总结 前言 在…

Python之数值和内建函数

Python之数值和内建函数 内建常用数据类型 分类 数值型 int、float、complex、bool 序列sequence 字符串str、字节序列bytes、bytearray列表list、元组tuple 键值对 集合set、字典dict 取整 取整 int // round math.floor math.ceil说明:两条//斜杠是整除&…

(云HIS)云医院管理系统源码 SaaS模式 B/S架构 基于云计算技术

通过提供“一个中心多个医院”平台,为集团连锁化的医院和区域医疗提供最前沿的医疗信息化云解决方案。 一、概述 云HIS系统源码是一款满足基层医院各类业务需要的健康云产品。该系统能帮助基层医院完成日常各类业务,提供病患预约挂号支持、收费管理、病…

快速掌握高效批量分割长视频技巧,让你的视频制作更轻松

对于需要处理大量长视频的影视制作人员来说,视频分割是一项必不可少的任务。传统的视频分割方法需要手动进行,费时费力。今天,笔者将介绍一种快速批量分割长视频的方法,使用固乔智剪软件,提高视频制作效率。 1. 下载并…