线程池系列一:线程池原来是个外包公司,打工人我悟了

我们在工作中经常用到线程池,线程池(Thread Pool)是一种基于池化思想管理线程的工具。

线程的作用是处理任务,而池则是帮助我们实现资源的重复利用和管理。线程池就是帮助我们异步处理任务的工具

很多时候技术设计思想往往可以从现实中找到映射的。
将线程池比作一个外包公司,那么提交给线程池的任务则可类比为给外包的需求,线程池中的线程则是外包公司内的打工人

带着这种类比思想,我们开始了解下线程池的原理。

1、线程池的创建

线程池系列一:线程池原来是个外包公司,打工人我悟了

corePoolSize:核心线程数(默认核心线程数不销毁,但allowCoreThreadTimeOut参数为true时也是允许销毁的)
maximumPoolSize:线程池容许的最大线程池数
keepAliveTime和TimeUnit:线程空闲的最长时间
BlockingQueue:存储多余任务的有限阻塞队列
ThreadFactory:创建执行任务的线程的工厂
RejectedExecutionHandler:拒绝策略

2、外包公司的运行模式

通过threadPoolExecutor.execute(runnable);执行Runnable任务

线程池系列一:线程池原来是个外包公司,打工人我悟了
外部将任务交付给线程池(甲方将需求交付给外包公司)

2.1、线程池内线程少于一定数量(corePoolSize),则创建线程来处理任务(每来一个任务,创建一个线程处理)

即:外包公司开始招人处理需求,人数达到一定数量后(公司认为一般情况下,这些人足以支持公司运营)

2.2、当线程总数达到指定数量(corePoolSize)后,仍有任务交付给线程池,此时线程池将任务暂存到队列(BlockingQueue,容量有限)中

即:甲方交付的需求过多时,外包公司则暂时将需求压下(压下的数量有限),等有人手空闲下来再处理。

2.3、队列装满之后,仍有多余任务,则类似第2步,为每个任务创建线程进行处理

即:当积压的需求超过公司承受能力时,公司开始又找人(直到到达公司人数上限)

2.4、当线程池总数量达到指定数量(maximumPoolSize)后,便不再创建。于是将多余任务进行特殊处理(拒绝策略)

即:需求再多时,外包公司已无力接手这些需求,于是拒绝这些任务(按某种方式处理这些需求,比如丢弃 或 让甲方自行处理)

3、打工人的艰辛

线程池系列一:线程池原来是个外包公司,打工人我悟了
/**线程池内线程是以Worker的形式存在,因此总线程就是Worker集合*/
private final HashSet workers = new HashSet();

在上面的2.1和2.3中,每来一个任务,线程池创建一个线程处理

3.1、将首个要执行的任务(firstTask)和线程(thread)封装到worker对象(worker本身就是一个Runnable)中,并用thread执行worker任务。

Worker(Runnable firstTask) {
     setState(-1); // inhibit interrupts until runWorker
     this.firstTask = firstTask;
     this.thread = getThreadFactory().newThread(this);
  }

/** Delegates main run loop to outer runWorker  */
public void run() {
      runWorker(this);
}

3.2、worker的run方法只干一件事,就是while循环执行任务
(先处理firstTask,处理完后便从队列中获取任务)。

线程池系列一:线程池原来是个外包公司,打工人我悟了

3.3、如果没有可执行的任务,worker也就结束了,自然thread也就可以销毁了

即:打工人进入公司,从此007不归路
要么在执行任务,要么在获取任务的路上。直到确定没有可处理的任务时就结束了(打工人打工魂)

4、打工人离职的方式

线程池系列一:线程池原来是个外包公司,打工人我悟了

线程池的状态及变化过程:
RUNNING < SHUTDOWN < STOP < TIDYING < TERMINATED

4.1、线程池关闭时(状态变为SHUTDOWN且队列中没有了任务;或者 状态至少是STOP时),所有线程分别在完成正在执行的任务后,逐个销毁

即:公司倒闭了,所有员工完成手头任务后,纷纷离职

4.2、线程池线程总数超过maximumPoolSize后,多余的数量被所有线程CAS竞选,竞选到的则销毁

即:公司人数过多,需要优化部分名额。所有员工都可以竞选资格,竞选上的就离职了

4.3、当线程一段时间(keepAliveTime)内都没有获取到任务,且该线程可以被销毁(可以被销毁的判定条件:线程总数超过corePoolSize 或者 线程池中声明包括核心线程都可以被销毁),多余的数量被所有线程CAS竞选,竞选到的则销毁

即:公司人数超过人数下限(甚至公司声明没有人数下限)时,当有人一段时间内都没有处理业务时,此人就离职了

4.4、队列中只要仍有任务,就至少有一个线程存活;当队列没有任务时,可以容许所有线程都销毁

即:要任务时最少要留一人处理,没任务时是可以都离职的

总结

  • 任务加入到线程池后
    先尝试创建核心线程来处理;
    若达到核心线程数上限,则则加入队列;
    若队列已满,则尝试创建最大线程来处理;
    若达到最大线程数,则只能按照拒绝策略处理
  • 线程池中线程生命周期
    线程池伴随任务创建线程并复用线程,循环从队列中获取任务执行
    线程池销毁时机
    线程池销毁时所有线程都要销毁
    线程池中的线程数量超过上限(maximumPoolSize)时,多余销毁
    当线程空闲一段时间未处理任务,此线程要销毁(若允许销毁)
    当队列没有任务时,否则至少有一个线程存活,下限为0;

Original: https://www.cnblogs.com/mlwy/p/15447139.html
Author: zy苦行僧
Title: 线程池系列一:线程池原来是个外包公司,打工人我悟了

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/576382/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Debezium的基本使用(以MySQL为例)

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。 GreatSQL是MySQL的国产分支版本,使用上与MySQL一致。 一、Debezium介绍 摘自官…

    数据库 2023年5月24日
    0101
  • MySQL CREATE TABLE 简单设计模板交流

    我们也可以多台机器部署, 设置不同 AUTO_INCREMENT step, 让每个 sequece 产生不同号码. 例如部署 step = 2 个服务结点, 并行获取数据. 一个…

    数据库 2023年5月24日
    0128
  • 【黄啊码】MySQL入门—6、掌握这些数据筛选技能比你学python还有用-2

    大家好!我是黄啊码,上节课我们将了DISTINCT、 FROM 、 GROUP BY、 HAVING 、 ORDER BY 这些筛选数据的技能,是不是总感觉少了些啥? 你:啊码,你…

    数据库 2023年6月16日
    0112
  • 2022-8-18 第六组 JDBC

    JDBC 1. 概念:Java DataBase Connectivity Java 数据库连接, Java语言操作数据库 JDBC本质:其实是官方(sun公司)定义的一套操作所有…

    数据库 2023年6月14日
    081
  • 重新学习数据库(2)

    单元概述 通过本章的学习能够了解MySQL数据库中多表查询的含义,掌握多表查询的基本写法,掌握特殊的多表查询的写法,掌握内连接和外连接的区别 测试数据脚本 drop TABLE e…

    数据库 2023年6月16日
    0186
  • mysql基本数据类型

    概述 要想学好mysql,了解其支持的基本数据类型以及内部原理是极为重要的,只有这样,我们才能根据不同的业务要求来选择不同的数据类型,实现最佳的存储效果和查询性能,因而本文就着重总…

    数据库 2023年5月24日
    0131
  • 量子物理

    今天刷了YouTube的量子物理了解到了量子物理的发展史从微观到相对论从原子核到量子纠缠何其快哉 物理学:经典物理,量子物理。经典物理:万有引力量子物理:相对论 Original:…

    数据库 2023年6月11日
    077
  • springboot~用正则表达式提取bearer token

    前后一体的应用,是这样进行认证的 用户向服务端发送验证信息(用户名、密码); 服务端验证成功就向用户返回一个sessionid; 服务端保存了这个session_id对应的信息,并…

    数据库 2023年6月6日
    094
  • Spark知识点总结

    Spark基础 Spark优势 优秀的数据模型与丰富计算抽象 Spark 借鉴了 MapReduce 思想发展而来,保留了其分布式并行计算的优点并改进了其明显的缺陷。 让中间数据存…

    数据库 2023年6月6日
    077
  • windows安装mysql8.0.29(ZIP解压安装版本)

    一. 下载mysql 8.0.29软件包 二. 解压,初始化安装 1,打开下载后文件所在目录,使用解压软件解压,打开文件夹!(如图,文件路径不要出现中文!) 2,创建my.ini文…

    数据库 2023年6月16日
    081
  • centos系统下mysql的配置

    配置文件路径 /etc/my.cnf Hole yor life get everything if you never give up. Original: https://ww…

    数据库 2023年6月9日
    067
  • win10彻底永久关闭自动更新的方法【已验证有效】

    [知识整理/来源网络] 原文链接:win10彻底永久关闭自动更新的方法【已验证有效】_电脑知识-电脑配置网 (dnpz.net) win10的自动更新可谓是非常顽固,很多用户在网上…

    数据库 2023年6月9日
    0108
  • day02-用户登录功能实现

    多用户即时通讯系统02 4.编码实现01 4.1功能实现-用户登录 4.1.1功能说明 因为还没有学习数据库,我们人为规定 用户名/id = 100,密码为 123456 就可以登…

    数据库 2023年6月11日
    0108
  • 【已解决】关于echarts的splitArea分割区域背景闪烁问题

    (x轴)使用时间类型(type: “time”),并且x轴使用splitArea划分后使用color属性设定分割区域颜色。同时使用dataZoom设置区域缩…

    数据库 2023年6月6日
    081
  • 第十六章 Spring动态代理详解

    MethodInterceptor(方法拦截器) public class Arround implements MethodInterceptor { /* invoke方法: …

    数据库 2023年6月14日
    079
  • 主从复制架构直接转换MGR(manual)

    IP port role info 192.168.188.81 3316 node1 master 192.168.188.82 3316 node2 slave1 192.16…

    数据库 2023年6月16日
    0217
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球