ThreadPoolExecutor详解(上)

news/2025/2/21 7:09:06/

为什么会有线程池?

如果客户端发一个请求,服务端就创建一个线程接收请求,线程资源是有限的,而且创建一个线程和执行结束之后都要调用操作系统资源销毁线程,这样频繁操作肯定非常占用cpu和内存资源,线程池的作用就是实现线程的资源复用和控制最大线程数,还有队列异步处理请求,这样就减少线程资源的浪费

一、ThreadPoolExecutor参数如何设置

核心线程数(corePoolSize)、最大线程数(maximumPoolSize)

可以根据三个方面进行分析:

  • CPU密集型任务:要避免线程的上下文切换,所以尽量要少创建线程,把corePoolSize设置成CPU核心数+1(加1是为了避免当中有的线程因为特殊情况被挂起,为了尽可能的利用CPU资源)
  • IO密集型任务:当线程操作IO资源时,CPU资源是闲置的,我们可以尽可能创建合适的线程数来压榨CPU资源,IO时间越长,可以设置更多的线程数,但是不一定越多越好,我们可以通过这个公式来计算:线程数=CPU核心数*(1+线程等待时间/线程运行总时间)
  • 混合型任务

总时间-总时间(CPU)=线程等待时间

理想状态下可这样估算,但是系统可能运行有其它线程,所以要进行压测

jmeter压测:

pom.xml文件配置:

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.0</version><relativePath/> <!-- lookup parent from repository --></parent>
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>

java代码:

@SpringBootApplication
public class Application {public static void main(String[] args){SpringApplication.run(Application.class, args);}
}@RestController
public class TestController {@GetMapping("/test")public String test() throws InterruptedException {Thread.sleep(1000);return "test";}
}

 jmeter压测操作:

 

 添加聚合报告

添加结果树视图

聚合结果报告

默认最大200个连接,总执行时间25s,平均响应时间(Average)4.2s,最小响应时间(Min)1s,最大响应时间(Max)8s,请求错误率(Error)0%,吞吐量(Throughput)每秒钟完成125.5个请求

设置最大800个连接,总执行时间9s,平均响应时间(Average)1.2s,最小响应时间(Min)1s,最大响应时间(Max)2.5s,请求错误率(Error)0%,吞吐量(Throughput)每秒钟完成560.6个请求

 基本上压测最大连接数值如果平均响应时间和执行总时间趋于稳定为准

 总结:

  • CPU密集型任务:CPU核心数+1
  • IO密集型任务:抽样系统高峰期CPU执行时间,再先通过公式算出理论值,然后通过理论值进行压测
  • 压测的业务如果是核心业务,并发量高,比如1s需要处理1000个请求,corePoolSize和maximumPoolSize都可以设置成500,如果是非核心业务,并发量小,核心线程数保留10个就行,最大线程数设置1000
  • 队列大小需要根据线程1s能处理多少请求,比如1s能处理100个请求,队列中有300个任务,也就是说任务可能要等3s才能处理完,如果不能接受这个时间就要限制队列大小

二、ThreadPoolExecutor具体执行过程

1、JUC包下ThreadPoolExecutor执行流程

核心线程来一个任务创建一个线程,提交任务数超过核心线程数会放到队列中,队列中放不下会在小于maximumPoolSize前提又创建新任务,核心线程和非核心线程任务都做完了,都会到队列中去拿任务

2、tomcat的ThreadPoolExecutor执行流程

创建ThreadPoolExecutor对象时就已经初始化好了核心线程

三、ThreadPoolExecutor如何关闭

正常关闭、异常关闭、手动调用shutdown()、shutdownNow()方法

https://www.processon.com/view/link/64cb797372e1a4480965cf86

为什么线程池执行任务时抛出异常会重新创建一个线程?

方便做线程异常处理,如果直接忽略导致无法处理异常,所以让它抛出异常终止,然后重启一个线程

ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 100, 1000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(100), new ThreadFactory() {@Overridepublic Thread newThread(Runnable r) {Thread thread = new Thread(r);thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {@Overridepublic void uncaughtException(Thread t, Throwable e) {System.out.println("拦截异常");}});return thread;}});

http://www.ppmy.cn/news/1002124.html

相关文章

Scratch Blocks自定义组件之「下拉图标」

一、背景 由于自带的下拉图标是给水平布局的block使用&#xff0c;放在垂直布局下显得别扭&#xff0c;而且下拉选择后回修改image字段的图片&#xff0c;这让我很不爽&#xff0c;所以在原来的基础上稍作修改&#xff0c;效果如下&#xff1a; 二、使用说明 &#xff08;1&am…

STM32CUBUMX配置RS485 modbus STM32(从机)亲测可用

———————————————————————————————————— ⏩ 大家好哇&#xff01;我是小光&#xff0c;嵌入式爱好者&#xff0c;一个想要成为系统架构师的大三学生。 ⏩最近在开发一个STM32H723ZGT6的板子&#xff0c;使用STM32CUBEMX做了很多驱动&#x…

【iOS】—— 循环引用问题总结

循环引用 文章目录 循环引用1.自循环引用2.相互循环引用3.多循环引用 常见的循环引用问题1.delegate解决方法&#xff1a; 2.block解决方法&#xff1a;1.强弱共舞2.把当前类作为block的参数3.用__block修饰变量&#xff0c;在block内部置nil 3.NSTimer解决方案&#xff1a;1.使…

powershell脚本写一个托盘图标

1、准备ico格式图标 star_bethlehem_icon 文件名改为star.ico 2、安装VSCode 如何下载安装VSCode 扩展&#xff1a;PowerShell扩展 3、创建项目 1、运行PowerShell命令 mkdir trayicon_ps1;cd trayicon_ps1;New-Item trayicon.ps1;code .2、将star.ico放入trayicon_ps1文…

day1-牛客67道剑指offer-JZ4 JZ6 JZ7 JZ9 JZ11 JZ69 JZ70 替换空格 斐波那契数列及其变形 左移/右移运算符

文章目录 1. JZ4 二维数组中的查找暴力法右上角往左下角逼近二分查找-左闭右开区间 2. 替换空格3. JZ6 从尾到头打印链表4. JZ7 重建二叉树思路1哈希加速 5. JZ9 用两个栈实现队列6. JZ11 旋转数组的最小数字常规遍历二分法 7. 斐波那契数列动态规划递归 8. JZ69 跳台阶动态规划…

2023华数杯数学建模C题思路分析 - 母亲身心健康对婴儿成长的影响

# 1 赛题 C 题 母亲身心健康对婴儿成长的影响 母亲是婴儿生命中最重要的人之一&#xff0c;她不仅为婴儿提供营养物质和身体保护&#xff0c; 还为婴儿提供情感支持和安全感。母亲心理健康状态的不良状况&#xff0c;如抑郁、焦虑、 压力等&#xff0c;可能会对婴儿的认知、情…

Spring Boot 常见的底层注解剖析

Spring Boot 是一个用于创建独立的、基于Spring框架的Java应用程序的框架。它提供了许多注解&#xff0c;用于配置和定制应用程序的行为。以下是一些常见的Spring Boot底层注解的剖析&#xff1a; 常见的Spring Boot底层注解的剖析 SpringBootApplication&#xff1a;这是一个…

MySQL语法2

DQL语句介绍 DQL是数据查询语言&#xff0c;用来查询数据库中表的记录 DQL-基本查询语句 SELECT 字段列表 FROM 表名列表 WHERE 条件列表 GROUP BY 分组字段列表 HAVIMG 分组后条件列表 ORDER BY 排列字段列表 LIMIT 分页参数 讲解过程&#xff1a;基本查询、条件查询…