当前位置:网站首页>线程池的创建及参数设置详解
线程池的创建及参数设置详解
2022-08-05 06:43:00 【李孛欢】
一. 常见线程池
线程池的创建方法主要有两类,第一是通过Executors 创建线程池,第二是通过 ThreadPoolExecutor 创建线程池。
首先我们来看通过Executors 创建的线程池是什么样的
1. Executors.newFixedThreadPool:创建⼀个固定大小的线程池,特点是核心线程数等于最大线程数,可控制并发的线程数,超出的线程会在有界队列中等待;
2. Executors.newCachedThreadPool:创建一个可缓存的线程池,特点是核心线程数为0,队列采用了SynchronousQueue,没有线程来take,任务不能put进去,若线程数超过处理所需,缓存⼀段时间后会回收,若线程数不够,则新建线程;
3. Executors.newSingleThreadExecutor:创建单个线程数的线程池,它可以保证先进先出的执行顺序;
4. Executors.newScheduledThreadPool:创建⼀个可以执⾏延迟任务的线程池;
5. Executors.newSingleThreadScheduledExecutor:创建⼀个单线程的可以执行延迟任务的线程池;
6. Executors.newWorkStealingPool:创建⼀个抢占式执行的线程池(任务执行顺序不确定)【JDK1.8 添加】。
一般不推荐使用Executors 的方式去创建线程池,而是通过ThreadPoolExecutor 根据项目实际去设置参数创建线程池,下面我们主要分析一下线程池核心参数的设置。
二. 线程池参数设置详解
在这个问题展开前,我们先来了解一下压测,即压力测试,是确立系统稳定性的一种测试方法,通常在系统正常运作范围之外进行,以考察其功能极限和和可能存在的隐患。
压测的目的就是通过模拟真实用户的行为,测算出机器的性能(单台机器的 QPS、TPS),从而推算出系统在承受指定用户数(100 W)时,需要多少机器能支撑得住。因此在进行压测时一定要事先设定压测目标值,这个值不能太小,也不能太大,按照目前业务预估的增长量来做一个合理的评估。
压测的一些名词解释:
首先,我们线程池的参数设置最后必须要通过压测来确定,需要符合我们的业务需求。那么我们如何开始进行压测参数配置的,也就是说压测前我们线程池的参数应该如何选取,这个问题需要分情况去讨论:
情况一:当前的线程池可以占用我们服务器的所有资源
基于先辈程序员的理论基础和实践,进行线程池的参数合理调整,然后经过压测,最终确定我们的参数。
例如:
- 计算密集型:CPU核数 + 1
- IO密集型:2 * CPU核数 or CPU利用率 * (1 + 等待时间 / 计算时间)* CPU核心数
情况二:当前线程池不可以使用机器的所有资源
由于我们目前机器不是单机部署的,分布式部署的情况,一个服务多个接口的情况,比如两个重要接口,三个可降级的接口,在这个场景下比如说一个重要接口里面需要创建一个线程池来提高单接口的处理速度,那么这个时候怎么去设置参数。也就是说,我这个线程池不能获得服务器的所有资源。
具体案例:需要拿到该服务各个接口的访问比例,比如4个接口,各个比例为 2 : 3 :1 : 1
两个核心服务接口(承载60%+)
A. 需要创建线程池,提高单接口处理速度,这时候怎么设置线程池参数(最核心的三个参数:最大线程数,核心线程数以及阻塞队列的选择)
- 第一个接口访问量占用 1 / 4:因此分配1/4的资源
- 第二个接口访问比例 3 / 8:因此分配 3/8 的资源
- 接下来确定最大线程数(贴合实际):不能随意的将一个线程池线程数加大,这样的话会导致其他接口不能雨露均沾,具体情况考虑CPU核数,所有接口的最大QPS,和本机活跃的live的线程数。拿到这些数据后再通过上述访问比例去分配资源。
- 核心线程数:初次压测设置成为一样大,测试最大并发访问的情况。撑得住,调小核心线程数。撑不住,我们还有一个阻塞队列去调整,接下来去确定阻塞队列
- 不推荐无界队列:使用无界队列相当于干掉了最大线程数这个参数,违背了线程池的设计初衷,还有无限积压请求,最终导致OOM问题。推荐使用有界队列:不推荐直接使用Integer.max_value,而是模拟我们访问量最大的场景来确定,将高峰访问时段与我们压测进行匹配,具体参数设置:(这个时段的访问数量 减去 这个时段接口能处理的请求数量)* 150%,也就是用我们接口能处理请求后剩余的值适当提升50%作为我们有界队列的上限。
- 设置完后进行压测
B. 案例情况:如果按照上述条件调整了,还没达到预期怎么办?
- 已经达到最大线程数3/8了,那就调大队列的最大等待数(首先调整队列而不是线程数)。好处:不影响其他接口,当前线程只是等待,而不是不可用
- 如果,业务方不同意上述等待方案:优化当前接口代码,把并发性调整一下,调高。
- 线程数适当再调大一点,但是不能再多很多了,否则会影响其他接口
- 添加机器
案例情况:如果线程核数设置不合理,会产生什么问题?
- 接口线程池设置太小,接口异常请求数量增多:如果使用抛异常降级策略,将会导致有大量的异常日志。会造成接口熔断或者降级(非正常性质的),导致生产事故。
- 接口线程池设置太大:当前接口活得挺好,但是会挤兑其他接口的资源,其他接口没有足够的资源,导致系统接口积压,系统崩溃。
总结:
- 先按照接口请求比例设置占用最大线程数
- 按照压测情况,适当设置核心线程数
- 按照最大情况,留出一定的等待队列阈值
- 饱和策略:按照具体情况具体分析
边栏推荐
- typescript59-泛型工具类型(partial )
- 自媒体人一般会从哪里找素材呢?
- 【动态类型检测 Objective-C】
- MySQL: order by sorting query, group by grouping query
- Redis
- 铠侠携手Aerospike提升数据库应用性能
- 2022 Fusion Welding and Thermal Cutting Operation Certificate Exam Questions and Mock Exams
- 栈与队列的基本介绍和创建、销毁、出入、计算元素数量、查看元素等功能的c语言实现,以及栈的压入、弹出序列判断,栈结构的链式表示与实现
- C# FileSystemWatcher
- Flink学习11:flink程序并行度
猜你喜欢
AI + video technology helps to ensure campus security, how to build a campus intelligent security platform?
Redis
【LeetCode】235.二叉搜索树的最近公共祖先
不太会讲爱,其实已经偷偷幸福很久啦----我们的故事
Summary of Text Characterization Methods
Put Cloudflare on the website (take Tencent Cloud as an example)
UDP broadcast
RNote108---Display the running progress of the R program
Flink Learning 11: Flink Program Parallelism
IO进程线程->进程间的通信->day7
随机推荐
17-VMware Horizon 2203 virtual desktop-Win10 manual desktop pool floating (seventeen)
【工具配置篇】VSCode 常用使用总结
女生做软件测试会不会成为一个趋势?
Hash these knowledge you should also know
typescript68-索引查询类型(查询多个)
Redis进阶
2022 Fusion Welding and Thermal Cutting Operation Certificate Exam Questions and Mock Exams
Week 8 Document Clustering
Re regular expressions
2022起重机司机(限桥式起重机)考试题库及模拟考试
不太会讲爱,其实已经偷偷幸福很久啦----我们的故事
【Dynamic type detection Objective-C】
武田公司2022财年第一季度业绩强劲;正稳步实现全年的管理层指引目标
Mysql主从延迟的原因和解决方案
2022 crane driver (limited bridge crane) exam question bank and simulation test
任务流调度工具AirFlow,,220804,,
protobuf根据有关联的.proto文件进行编译
开启防火墙iptable规则后,系统网络变慢
铠侠携手Aerospike提升数据库应用性能
技术分析模式(九)三重顶部和底部