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

线程池调优,深入理解,线程池各个参数的含义(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源码系列

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++ 利用容器适配器,仿函数实现栈,队列,优先级队列(堆),反向迭代器,deque的介绍与底层

C 利用容器适配器,仿函数实现栈,队列,优先级队列【堆】,反向迭代器,deque的介绍与底层 一.容器适配器的介绍二.利用容器适配器实现栈和队列1.stack2.queue 三.仿函数介绍1.什么是仿函数2.仿函数的使用3.函数指针的使用1.函数指针的用处2.利用函数指针完成回调3.利用仿函数完成回…

CSS之粘性定位

让我为大家介绍一下粘性定位吧&#xff01; 大家应该都了解过绝对定位&#xff0c;它是相对于父级定位 那么粘性定位相对于谁呢&#xff1f; 它相对于overflow:hidden; 如果没找到就会跟fixed固定定位一样&#xff0c;相对于视口 <!DOCTYPE html> <html lang"en…

实习日志5

活字格图片上传功能&#xff08;批量&#xff09; 这个报错真的恶心&#xff0c;又看不了他服务器源码&#xff0c;接口文档又是错的 活字格V9获取图片失败bug&#xff0c;报错404-CSDN博客 代码BUG记录&#xff1a; 问题&#xff1a;上传多个文件的base64编码被最后一个文…

76 C++对象模型探索。多重继承中虚函数表分析

多重继承非重点内容&#xff0c;在实际开发中使用的不多&#xff0c; 这里只是为了知识点的完整&#xff0c;记录一下。 直接上结论。 一个类&#xff0c;如果继承于多个基类&#xff0c;且这个多个基类中有虚函数&#xff0c;那么 这个类 会有多个 虚函数表。 这个 类的对…

THM学习笔记——john

John the Ripper是目前最好的哈希破解工具之一。 John基本语法&#xff1a; john [options] [path to file] john&#xff1a;调用John the Ripper程序。 [path to file]&#xff1a;包含你要尝试破解的哈希的文件&#xff0c;如果它们在同一个目录中&#xff0c;你就不需要命名…

Docker容器基本管理

目录 一、概述 &#xff08;一&#xff09;为什么要用到容器 &#xff08;二&#xff09;docker概念 1.镜像 2.容器 3.仓库 &#xff08;三&#xff09;Docker与虚拟机的区别 &#xff08;四&#xff09;Linux namespace的六大类型 二、安装docker容器引擎 &#xff…

光耦驱动继电器电路图大全

光耦驱动继电器电路图&#xff08;一&#xff09; 注&#xff1a; 1U1-1脚可接12V&#xff0c;也可接5V&#xff0c;1U1导通&#xff0c;1Q1导通&#xff0c;1Q1-30V&#xff0c;线圈两端电压为11.7V. 1U1-1脚不接或接地&#xff0c;1U1不通&#xff0c;1Q1截止&#xff0c;1…

Federated Optimization in Heterogeneous Networks —— Fedprox算法

Federated Optimization in Heterogeneous Networks 1. 论文信息 论文题目: Federated Optimization in Heterogeneous Networks Fedprox算法&#xff0c;plato小项目跑通并理解作者&#xff1a;Tian Li, Anit Kumar Sahu, Manzil Zaheer, Maziar Sanjabi, Ameet Talwalkar, …

使用阿里云的oss对象存储服务实现图片上传(前端vue后端java详解)

一&#xff1a;前期准备&#xff1a; 1.1&#xff1a;注册阿里云账号&#xff0c;开启对象存储oss功能&#xff0c;创建一个bucket&#xff08;百度教程多的是&#xff0c;跟着创建一个就行&#xff0c;创建时注意存储类型是标准存储&#xff0c;读写权限是公共读&#xff09;…

HNU-编译原理-甘晴void学习感悟

前言 熬过煎熬的考试周、复习以及更加煎熬的等成绩&#xff0c;查到成绩的那一刻&#xff0c;心里还是挺开心的。 虽然我没有完全学懂这门课程&#xff0c;但我还是兢兢业业地通过了课程的考试&#xff0c;拿到了这门课程的认可。 记录一下自己对编译原理的学习感悟&#xf…

python使用pyinstaller 快速打包成一个exe程序方案

使用PyInstaller是一种将Python脚本打包成独立可执行文件&#xff08;.exe&#xff09;的方便方法。 以下是一个简单的步骤&#xff0c;以及相关的说明和代码示例&#xff1a; 1.安装PyInstaller: pip install pyinstaller2.在终端中导航到你的Python脚本所在的目录: cd pat…

day32_CSS

今日内容 0 复习昨日 1 css属性 2 盒子模型 【重点】 3 css扩展属性 4 Bootstrap【重点】 0 复习昨日 1 表格标签 table表格里面有tr , (行)行内有单元格,td行合并,rowspan列合并,colspan 2 写出input标签type属性的值 文本框 text 密码框 password 单选框 radio 复选框 checkb…

在线教育系统开发:构建现代化学习平台

随着科技的迅速发展&#xff0c;在线教育系统在教育领域扮演着越来越重要的角色。本文将深入探讨在线教育系统的开发过程&#xff0c;涉及关键技术和代码实现。 技术选型 在开始开发之前&#xff0c;我们首先需要选择适合在线教育系统的技术栈。以下是一些常见的技术选项&am…

使用宝塔面板部署Nuxt3项目到云服务器上

1、前期准备 1&#xff09;准备一台云服务器2&#xff09; 在云服务器上安装宝塔面板软件应用&#xff0c;安装步骤可参考博客:使用宝塔面板部署Node.jsMysql服务和Vue3-Admin项目到云服务器上 2、进行Nuxt3项目的部署 1)、本地执行打包命令&#xff0c;输出以下两个文件目录…

Android系统开发之TimeZoneDetectorService浅析--上

一&#xff1a;问题描述&#xff1a; 客户有一个关闭通话功能的需求&#xff0c;根据MTK的配置方法关闭了大概8个宏开关后&#xff0c;实现通话功能&#xff0c;但是导致插好sim卡开机后&#xff0c;时间和时区不能更新的问题。 二&#xff1a;问题分析&#xff1a; (1).MTK…

AF700 NHS 酯,AF 700 Succinimidyl Ester,一种明亮且具有光稳定性的近红外染料

AF700 NHS 酯&#xff0c;AF 700 Succinimidyl Ester&#xff0c;一种明亮且具有光稳定性的近红外染料&#xff0c;AF700-NHS-酯&#xff0c;具有水溶性和 pH 值不敏感性 您好&#xff0c;欢迎来到新研之家 文章关键词&#xff1a;AF700 NHS 酯&#xff0c;AF 700 Succinimid…

深度视觉目标跟踪进展综述-论文笔记

中科大学报上的一篇综述&#xff0c;总结得很详细&#xff0c;整理了相关笔记。 1 引言 目标跟踪旨在基于初始帧中指定的感兴趣目标( 一般用矩形框表示) &#xff0c;在后续帧中对该目标进行持续的定位。 基于深度学习的跟踪算法&#xff0c;采用的框架包括相关滤波器、分类…

pcl+vtk(十四)vtkCamera相机简单介绍

一、vtkCamera相机 人眼相当于三维场景下的相机&#xff0c; VTK是用vtkCamera类来表示三维渲染场景中的相机。vtkCamera负责把三维场景投影到二维平面&#xff0c;如屏幕、图像等。 相机位置&#xff1a;即相机所在的位置&#xff0c;用方法vtkCamera::SetPosition()设置。 相…

力扣hot100 腐烂的橘子 BFS 矢量数组 满注释版

Problem: 994. 腐烂的橘子 文章目录 思路复杂度&#x1f49d; Code 思路 &#x1f468;‍&#x1f3eb; 参考 复杂度 时间复杂度: O ( n ) O(n) O(n) 空间复杂度: O ( n ) O(n) O(n) &#x1f49d; Code class Solution {int[] dx new int[] { 0, 1, 0, -1 };// 行 矢…

如何快速搭建实用的爬虫管理平台

目录 一、前言 二、选择合适的爬虫框架 三、搭建数据库 步骤1 步骤2 步骤3 四、搭建Web服务器 步骤1 步骤2 步骤3 步骤4 五、管理爬虫 六、总结 一、前言 爬虫是互联网数据采集的关键工具&#xff0c;但是随着数据量的增加和需求的多样化&#xff0c;手动运行和管…