线程池调优,深入理解,线程池各个参数的含义(keepAliveTime 展开说说?)

news2024/10/2 1:39:57

线程池调优,深入理解,线程池各个参数的含义(keepAliveTime 展开说说?)目录

    • 线程池核心组件
    • 核心线程、最大线程、阻塞队列的关系(重点)
    • 线程池调优(运行流程)
    • keepAliveTime是个啥?
    • 总结

昨天被别人问到线程池中的 keepAliveTime 的含义是什么了。还有线程池中每个参数是什么意思,只记得当时上大学那会看过 ThreadPoolExecutor 的源码,当时看的挺细的,但是现在都过了好几年了我都忘的差不多了,都是一通乱答的哈哈哈哈哈哈。今天来复盘一下。
在这里插入图片描述

线程池核心组件

  • 拒绝策略:没啥好说的就是任务被线程池拒绝后的处理策略

  • work:实现了 Runnable 的一个类,work 里面包了一个 thread,当 work 运行的时候本质会执行 work 类中的 run 方法。(说白了 work 就是正在干活的线程)

  • 最大线程数:同时干活的 work 的最大个数

  • 核心线程数:相当于守护进程的个数,核心干活的 work,带编制的 wrok。永远都不会被开除。源码如下

在这里插入图片描述

空闲线程数:最大线程数-核心线程数 = 可空闲的线程的最大数

核心线程、最大线程、阻塞队列的关系(重点)

先来讲一个小故事,在互联网还没发展的早期出现一个巨头公司,名字叫做小咸鱼牌小饼干(ThreadPoolExecutor),它里面每天有大量的任务需要处理(threadPoolExecutor.submit(new Task(i))),十分的缺人,现有的骨干完全不够用(核心线程数不够用)。加上有些外包进来的人员流动性大,离职后手上的工作也需要交接进行缓冲(BlockingQueue阻塞队列缓冲),为了让公司做大做强,很多核心骨干自高奋勇,主动去解决外包留下来的交接任务(核心线程做完自己的任务后,会去阻塞队列中拿任务执行),过了一段时间,骨干们吃不消了,开始每天骂骂咧咧的,公司看不下去了,想着去招聘点外包解决遗留下来的任务,招聘前先看看自己包里的经费够不够,发现经费够(阻塞队列满了、核心线程满了、空闲线程数还有位置),于是招了几个外包进来,咔嚓咔嚓的一顿弄,终于在外包、骨干的一顿努力下。遗留下来的交接任务干完了(阻塞队列中没任务了)。这个时候外包合同到期了(keepAliveTime到期),既然没活了,外包们就地解散,骨干留下就行。 妈的看完这个源码我直冒冷汗,难道这就是人生的底层逻辑吗。
在这里插入图片描述

简化版描述就是:核心线程满了,后续的任务会放到阻塞队列,阻塞队列满了后,会安排空闲线程处理任务,当空闲线程加核心线程的总数,大于了最大线程数时,将会触发拒绝策略

最大线程=核心线程+空闲线程 公司规模=骨干+外包

空闲线程产生的条件 = 核心线程满了、阻塞队列满了后,新来的 task 都会被新开的线程执行,新开一个线程的前提条件是:最大线程数 - 核心线程 > 0

线程池调优(运行流程)

简单写一个如下线程池,根据你对线程池的理解,说说一说它能抗最大并发是多少?答案是可以顺时并发处理 5 个任务(超一个任务都会被拒绝)。但是只有 4 个线程去处理任务。还有一个任务在阻塞队列里面。
公式就是:线程池可瞬时处理的任务数量 = 最大线程数+阻塞队列长度
在这里插入图片描述

线程池可瞬时处理的任务数量 = 最大线程数+阻塞队列长度这个公式靠谱吗怎么来的?编写测试用例,发 6 个请求过来,可以看到有一个被拒绝了。就从这个请求被拒绝的流程来展开讲讲吧。
在这里插入图片描述
任务 1、2进来的时候被俩个核心线程处理,直接被 addWork 了,此时的工作线程数是 2。
在这里插入图片描述
第 3 个任务进来的时候,走如下分支,发现核心线程数满了,直接丢到阻塞队列中。并且后续判断 work 的数量是否等于 0 ,发现不满足,任务 3 仅仅是丢到阻塞队列中了而已。
在这里插入图片描述
此时任务 4、5 过来了,发现核心线程满了、阻塞队列满了,执行下面圈红的第三个分支,进行 addWork(command,false)。注意传的是 false!!!!里面会拿,正在工作的 work 数量与最大线程数比较,发现:正在工作的 work 数量 < 最大线程数。接着开辟空闲线程去处理任务 4、5。
在这里插入图片描述
此时任务 6 过来了,发现: 正在工作 work的数量 = 最大线程数。此时正在工作的 work 有(任务 1、2、4、5)4 个。然后直接被拒绝触发拒绝策略。整个流程就是这样的。搞清楚各个参数的触发时机后,心中有粮调优不慌。
,

keepAliveTime是个啥?

其实不管是核心线程还是什么空闲线程还是最大线程,这么一大堆乱七八糟的概念,本质最终都是需要进行处理任务的,处理任务的逻辑在runWork()中。如下图

  • 圈红的 task:当前 work 本职的工作任务
  • 圈黄的 task:从阻塞队列中拿出来的工作任务
  • 圈绿的地方:执行任务具体Runnable 中的 run 方法。

从源码图中是不是印证了我一开始的那个小故事,骨干员工干完了分配给自己的活后,主动为公司解决超量的任务
在这里插入图片描述
而 keepAliveTime 这个参数就在 getTask 方法里面进行体现,其实就是调用的阻塞队列中的 poll 方法,当队列中的任务为空时,等待 keepAliveTime 时间后再去取任务,还取不到任务就返回 null。

在这里插入图片描述
空闲线程拿不到任务结果就是,task 拿到的是 null,触发 processWorkerExit(w, completedAbruptly); 逻辑,空闲线程就被销毁了。因此叫做空闲线程的最大存活时间是这么来的!
在这里插入图片描述

总结

  1. 核心线程满了,后续的任务会放到阻塞队列,阻塞队列满了后,会安排空闲线程处理任务,当空闲线程加核心线程的总数,大于了最大线程数时,将会触发拒绝策略
  2. 核心线程满了,后续的任务会放到阻塞队列,阻塞队列满了后,会安排空闲线程处理任务,当最大线程数-核心线程数>0,此时会安排空闲线程处理进来的这个任务。
  3. 当阻塞队列中的任务没有了的时候,由于底层是通过调用 poll 方法拿阻塞队列中的任务的,过了keepAliveTime时候后,还拿不到任务,这个空闲线程就最终会被销毁。

不说了,大家赶紧去看看线上的线程池配置是否合理,后续主页持续更新:如何合理针对计算密集型、io 密集型、自定义拒绝策略收集异常日志,常见业务进行线程池参数设置以及调优~这里是小咸鱼的技术窝,欢迎拜访

在这里插入图片描述
推荐好文:

知其然而知其所以然~线程池深入源码分析-手把手debug源码系列

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

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

相关文章

如何学习VBA_3.2.12.13:VBA中工作表函数的利用

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的劳动效率&#xff0c;而且可以提高数据处理的准确度。我推出的VBA系列教程共九套和一部VBA汉英手册&#xff0c;现在已经全部完成&#xff0c;希望大家利用、学习。 如果…

docker 修改默认存储位置

✨✨✨✨✨✨✨ &#x1f380;前言&#x1f381;查看前面docker储存位置&#x1f381;移动文件位置&#x1f381;修改配置文件docker.service&#x1f381;修改daemon.json&#x1f381;加载配置并重启 &#x1f380;前言 最近服务出现系统盘满了,发现其中docker存储占用很大一…

1块9毛钱,修复拓牛TC1D智能垃圾桶盖子不能正常开合的故障

前言 21年9月份买了拓牛的智能垃圾桶&#xff0c;一直用的很流畅&#xff0c;再加上屋里没啥有机垃圾&#xff0c;也没有宠物&#xff0c;用上之后每次投入垃圾&#xff0c;之后都会盖上盖子&#xff0c;没有很多的异味散发&#xff0c;屋里也没有蟑螂等害虫。 再加上门口有帘…

SpringBoot使用druid

SpringBoot使用druid 一、前言二、配置1、pom依赖2、配置文件yml3、配置类 一、前言 Java程序很大一部分要操作数据库&#xff0c;为了提高性能操作数据库的时候&#xff0c;又不得不使用数据库连接池。 Druid 是阿里巴巴开源平台上一个数据库连接池实现&#xff0c;结合了 C…

C#,获取与设置Windows背景图片的源代码

为了满足孩子们个性化桌面的需求。 这里发布获取与设置Windows背景图片的源代码。 1 文本格式 using System; using System.IO; using System.Data; using System.Linq; using System.Text; using System.Drawing; using System.Collections; using System.Collections.Gene…

老旧小区火灾频发,LoRa无线系统筑牢安全防线

近日&#xff0c;全国各地多个老旧小区火灾事故频发&#xff0c;从安微合肥南二环一老旧小区居民楼起火、上海金山区一小区居民楼火灾&#xff0c;到1月24日江西新余市特大火灾......都造成了不同程度的人员伤亡和财产损失&#xff0c;令人扼腕痛惜&#xff0c;教训十分深刻。 …

4.Hive表更新字段信息,一次讲明白

Hive表更新字段信息 一、更新表字段语句1、修改字段名称2、修改字段类型3、修改字段备注 二、总结 一、更新表字段语句 ALTER TABLE table_name [PARTITION partition_spec] CHANGE [COLUMN] col_old_name col_new_name column_type[COMMENT col_comment] [FIRST|AFTER column…

【医学图像数据增强】 EMIT-Diff:扩散模型 + 文本和结构引导,生成多样化且结构准确的医学图像

EMIT-Diff&#xff1a;扩散模型 医学图像生成 提出背景方法步骤优化目标如何将不同的条件输入&#xff08;例如文本或边界框&#xff09;整合到模型中&#xff1f;如何提高边缘检测的准确性&#xff0c;从而生成真实和有意义的医学图像&#xff1f;如何使用自动编码器架构和大…

python写一个彩票中奖小游戏修订版本

先说规则&#xff1a; print("下面介绍双色球颜色规则:")print("一等奖,投注号码与当期开奖号码全部相同&#xff08;顺序不限&#xff0c;下同&#xff09;&#xff0c;即中奖")print("二等奖:投注号码与当期开奖号码中的6个红色球号码相同,即中奖&q…

详解SpringCloud之远程方法调用神器Fegin

第1章:引言 咱们作为Java程序员,在微服务领域里,Spring Cloud可谓是个耳熟能详的大名。它提供了一套完整的微服务解决方案,其中就包括了服务间的通信。在这个微服务中,有一个成员特别引人注意,它就是Feign。 那Feign到底是什么呢?简单来说,Feign是一个声明式的Web服务…

Windows7关闭谷歌浏览器提示“若要接收后续 Google Chrome 更新,您需使用 Windows 10 或更高版本”的方法

背景 电脑比较老&#xff0c;系统一直没有更新&#xff0c;硬件和软件版本如下&#xff1a; 操作系统版本&#xff1a;Windows7 企业版 谷歌浏览器版本&#xff1a;109.0.5414.120&#xff08;正式版本&#xff09; &#xff08;64 位&#xff09; 该版本的谷歌浏览器是支持…

2023年CSDN年底总结-独立开源创作者第一年

2023年最大的变化&#xff0c;就是出来创业&#xff0c;当独立开源创作者&#xff0c;这一年发起SolidUI开源项目&#xff0c;把知乎重新开始运营起来。CSDN粉丝破万&#xff0c;CSDN博客专家和AI领域创作者。 2023年年度关键词&#xff1a;创业 https://github.com/CloudOrc…

c语言实现—动态通讯录

一.前言 上次带大家认识了一下顺序表&#xff0c;其实我们可以在顺序表的基础上实现一个通讯录的小项目&#xff0c;通讯录的本质仍然是顺序表&#xff0c;所以如果下面的代码你有问题的话&#xff0c;先去看看我的上篇文章哦~。 通讯录的功能大家应该都知道吧&#xff0c;这次…

记 Rxjava zip操作符遇到的问题

在项目中遇到了类似下面这样的代码 本意是希望当zip操作符中三个Observable执行完毕之后&#xff0c;将他们返回的数据统一进行处理 Observable.zip(startFirst(), startSecond(), startThird(),(first, second, third) -> {Log.i("Rxjava", "handle all dat…

鸿蒙开发(八)添加常用控件(下)

添加控件的文章分成了上下两篇&#xff0c;上篇介绍了文本显示、文本输入、按钮、图片、单选框、切换按钮这六种常用控件&#xff0c;本篇继续介绍其他几种很重要但略微复杂的控件。 鸿蒙系列上一篇&#xff1a; 鸿蒙开发&#xff08;七&#xff09;添加常用控件&#xff08;…

网络安全防御保护实验(二)

一、登录进防火墙的web控制页面进行配置安全策略 登录到Web控制页面&#xff1a; 打开Web浏览器&#xff0c;输入防火墙的IP地址或主机名&#xff0c;然后使用正确的用户名和密码登录到防火墙的Web管理界面。通常&#xff0c;这些信息在防火墙设备的文档或设备上会有说明。 导…

[晓理紫]每日论文分享(有中文摘要,源码或项目地址)-机器人、强化学习

专属领域论文订阅 关注{晓理紫}&#xff0c;每日更新论文&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持 如果你感觉对你有所帮助&#xff0c;请关注我&#xff0c;每日准时为你推送最新论文。 分类: 具身智能&#xff0c;机器人强化学习开放词汇&…

[C++开发 03_2/2 _ STL(185)]

知识点1&#xff1a;STL初始 概述&#xff1a; STL是标准模板库的意思&#xff0c;STL从广义上来讲分为&#xff1a;容器&#xff0c;算法&#xff0c;迭代器。 容器算法之间通过迭代器进行无缝连接。 知识点2&#xff1a;STL初始 2.1 STL诞生 C中面向对象的三大特性&#xff1…

九、Kotlin 注解

1. 什么是注解 注解是对程序的附件信息说明。 注解可以作用在类、函数、函数参数、属性等上面。 注解的信息可用于源码级、编译期、运行时。 2. 注解类的定义 使用元注解 Retention 声明注解类的作用时期。 使用元注解 Target 声明注解类的作用对象。 定义注解类时可以声…

8.6 代理设计模式

文章目录 一、代理模式&#xff08;Proxy Pattern&#xff09;概述二、代理模式和观察者设计模式三、模式结构四、协作角色五、实现策略六、相关模式七、示例八、应用 一、代理模式&#xff08;Proxy Pattern&#xff09;概述 代理模式是一种设计模式&#xff0c;它通过引入一个…