线程池详解

线程池

什么是线程池:线程池就是管理一系列线程的资源池。

当有任务要处理时,直接从线程池中获取线程来处理,处理完之后线程并不会立即被销毁,而是等待下一个任务。

为什么要用线程池 / 线程池的好处:
  • **降低资源消耗。**通过重复利用已创建的线程降低线程创建和销毁造成的消耗

  • **提高响应速度。**当任务到达时,任务可以不需要等到线程创建久能立即执行。

  • **提高线程的可管理性。**统一管理线程,避免系统创建大量同类线程而导致消耗完内存。

线程池的应用:

比如我们系统 Web 服务器用的 Tomcat,Tomcat 处理每一个请求都会从线程连接池里面用一个线程去处理,又比如说我们连接数据库会用对应连接池 Druid德鲁伊等

还有实际开发中的定时任务,该任务的链路执行时间和过程都非常长,就会用一个线程池将该定时任务的请求进行处理。这样做好处就是可以及时返回结果给调用方,能够提高系统的吞吐量

// 请求直接交给线程池来处理 
public void push(PushParam pushParam) {try {pushServiceThreadExecutor.submit(() -> {handler(pushParam);});} catch (Exception e) {logger.error("pushServiceThreadExecutor error, exception{}:", e);}
}
如何创建线程池
  • 通过 ThreadPoolExecutor 构造函数来创建(推荐)
  • 通过 Executor 框架的工具类 Executors 来创建

为什么不推荐使用内置线程池(通过 Executor 框架的工具类 Executors 来创建):通过 ThreadPoolExecutor 构造函数的方式,这样的处理方式让开发人员更加明确线程池的运行规则,规避资源耗尽的风险

线程池常见参数有哪些
ThreadPoolExecutor 3个最重要的参数
  • corePoolSize:任何队列未达到队列容量时,最大可以同时运行的线程数量

  • maxinumPoolSize:当任务队列存放的任务达到队列容量的时候的最大线程数量。任何队列中存放的任务达到队列容量的时候,会创建新的线程运行任务。否则根据拒绝策略处理新任务。

  • workQueue:任务队列:新任务来的时候会先判断当前运行的线程数量是否达到核心线程数,如果达到的话,新任务就会被存放在队列中

    keepAliveTime:线程池中的线程数量大于 corePoolSize 的时候,如果这时没有新的任务提交,核心线程外的线程不会立即销毁,而是会等待,直到等待的时间超过了 keepAliveTime才会被回收销毁。非核心线程空闲后,保持存活的时间;设置为0,表示多余的空闲线程会被立即终止

    unit:keepAliveTime 参数的时间单位

    threadFactory:

    handler:饱和策略

线程池的饱和策略:
  • ThreadPoolExecutor.AbortPolity:抛出 RejectedExecutionException来拒绝新任务的处理
  • ThreadPoolExecutor.CallerRunsPolicy:
  • ThreadPoolExecutor.DiscardPolicy:
  • .DiscardPolicy:
  • .DiscardOldestPolicy:
如何处理这些参数 / 线程池大小怎么设置
CPU密集型任务(N + 1)

消耗CPU资源,将线程数设置为 N(CPU 核心数)+1,比 CPU 核心数多出来一个线程是为了防止线程阻塞、锁等原因导致的任务暂停带来的影响。一旦某个线程被阻塞,释放了 cpu 资源,多一个线程就可以充分利用 CPU 的空闲时间

IO密集型

系统会用大部分时间处理 I/O 操作,而线程等待 I/O 操作会被阻塞,释放CPU资源,这是就可以将 CPU 交出给其它线程使用。因此在 I/O 密集型任务应用中,可以多配置一些线程:

最佳线程数 = CPU核心数 * (1/CPU利用率) = CPU 核心数 * (1 + (I/O耗时 / CPU耗时))

线程池过小:当有大量请求需要处理,系统响应比较慢影响体验,甚至会出现在任务队列大量堆积导致OOM

线程池过大:大量线程同时争取 CPU 资源,这样会导致大量的上下文切换,增加线程执行时间,影响整体执行效率

CPU密集型、IO密集型

如果你的应用主要是利用cpu计算,也就是更多的是消耗cpu资源的话,那么就是cpu密集型,如果更多的是和IO相关的,比如接收一个前端请求--解析参数--查询数据库--返回给前端这样的,那么就是IO密集型的。

线程池处理任务的流程

图解线程池实现原理

  1. 如果当前运行的线程数小于核心线程数,那么就会新建一个线程来执行任务
  2. 如果当前运行的线程数等于或大于核心线程数,但是小于最大线程,那么就把该任务放入到任务队列里等待执行
  3. 如果向任务队列投放任务失败,但是当前运行的线程数是小于最大线程数的,就新建一个线程来执行任务
  4. 如果当前运行的线程数已经等同于最大线程数了,新建线程将会是当前运行的线程超出最大线程数,那么当前任务会被拒绝,饱和(拒绝)策略会调用RejectedExecutionHandler.rejectedExecution() 方法

Excetors 工具类提供了哪些线程池?有什么问题吗?

Excetors 工具类提供的常见线程池如下:

  • FixedThreadPool:固定线程数量的线程池。该线程池中的线程数量始终不变。当有一个新的任务提交时,线程池中若有空闲线程,则立即执行。若没有,则新的任务会被暂存在一个任务队列中,待有线程空闲时,便处理在任务队列中的任务。
  • SingleThreadExecutor:只有一个线程的线程池。若多余一个任务被提交到该线程池,任务会被保存在一个任务队列中,待线程空闲,按先入先出的顺序执行队列中的任务。
  • CachedThreadPool:可根据实际情况调整线程数量的线程池。线程池的线程数量不确定,但若有空闲线程可以复用,则会优先使用可复用的线程。若所有线程均在工作,又有新的任务提交,则会创建新的线程处理任务。所有线程在当前任务执行完毕后,将返回线程池进行复用。
  • ScheduledThreadPool:给定的延迟后运行任务或者定期执行任务的线程池。

Excetors 工具类提供的常见线程池的弊端如下:

  • FixedThreadPoolSingleThreadExecutor:使用的是无界的 LinkedBlockingQueue,任务队列最大长度为 Integer.MAX_VALUE,可能堆积大量的请求,从而导致 OOM。
  • CachedThreadPool:使用的是同步队列 SynchronousQueue, 允许创建的线程数量为 Integer.MAX_VALUE ,如果任务数量过多且执行速度较慢,可能会创建大量的线程,从而导致 OOM。
  • ScheduledThreadPoolSingleThreadScheduledExecutor:使用的无界的延迟阻塞队列DelayedWorkQueue,任务队列最大长度为 Integer.MAX_VALUE,可能堆积大量的请求,从而导致 OOM。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FPGA开源项目分享——基于 DE1-SOC 的 String Art 实现

导语 今天继续康奈尔大学FPGA课程ECE 5760的典型案例分享——基于DE1-SOC的String Art实现。 (更多其他案例请参考网站: Final Projects ECE 5760) 1. 项目概述 项目网址 ECE 5760 Final Project 项目说明 String Art起源于19世纪的数学…

Taro打包生成不同目录

使用taro init创建taro项目时,taro默认打包目录是: /config/index.js outputRoot:dist默认的目录,编译不同平台代码时就会覆盖掉,为了达到多端同步调试的目的,这时需要修改默认生成目录了,通过查看官方文…

【MySQL数据库 | 第二十六篇】InnoDB基本数据存储单元以及存在问题

前言: InnoDB作为MySQL中最常用的存储引擎之一,承载着许多数据库系统的关键任务,如事务管理、并发控制和数据完整性保障。 然而,就像任何技术一样,InnoDB也并非完美无缺。在深入了解其工作原理和特性的同时&#xff…

ExoPlayer停止更新,建议升级到AndroidX Media3

1. 大家常用的ExoPlayer地址:GitHub - google/ExoPlayer: An extensible media player for Android ExoPlayer是谷歌官方提供的媒体播放库,大家在开发项目中经常使用ExoPlayer播放音视频,谷歌官方已经明确表示该库在2024-04-03停止更新&…

鸿蒙Native输出so动态库,并提供给第三方导入使用

前言: DevEco Studio版本:4.0.0.600 API:9 最近在学习鸿蒙的Native输出so动态库,下面就给大家分享下我的学习心得及在实现过程中遇到的问题。 实现需求:通过so库输出文本内容 “你好,鸿蒙!” 参考资料…

CSS 使用 SVG 绘制动态皮筋与小球交互动画

CSS 使用 SVG 绘制动态皮筋与小球交互动画 效果展示 CSS 知识点 使用 animation 控制 SVG 的 path 属性执行动画使用 CSS 设置 SVG 部分属性 整体页面布局 <div class"elasic"><!-- 小球 --><div class"ball"></div><!-- 皮…

Nodejs 第六十二章(短链接)

短链接介绍 短链接是一种缩短长网址的方法&#xff0c;将原始的长网址转换为更短的形式。它通常由一系列的字母、数字和特殊字符组成&#xff0c;比起原始的长网址&#xff0c;短链接更加简洁、易于记忆和分享。 短链接的主要用途之一是在社交媒体平台进行链接分享。由于这些…

人工智能:更多有用的 Python 库

​ 目录 推荐 JupyterLab 入门 复杂的矩阵运算 其它人工智能和机器学习的 Python 库 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站 在进入主题之前&#xff0c;我们先讨论几个人…

利用Sentinel解决雪崩问题(二)隔离和降级

前言&#xff1a; 虽然限流可以尽量避免因高并发而引起的服务故障&#xff0c;但服务还会因为其它原因而故障。而要将这些故障控制在一定范围避免雪崩&#xff0c;就要靠线程隔离(舱壁模式)和熔断降级手段了&#xff0c;不管是线程隔离还是熔断降级&#xff0c;都是对客户端(调…

太赫兹探测器是太赫兹技术应用核心器件之一 我国研究成果不断增多

太赫兹探测器是太赫兹技术应用核心器件之一 我国研究成果不断增多 太赫兹探测器&#xff0c;是太赫兹&#xff08;THz&#xff09;应用的基础&#xff0c;是太赫兹成像、太赫兹通信等系统的核心器件&#xff0c;其性能直接决定太赫兹系统的优劣&#xff0c;地位极为重要&#x…

2024年同城网总流量全新生态,个人工作室落地式游戏玩法,单账户月入3万

我要为大家解读的是本地生活新项目&#xff0c;这个业务模式中&#xff0c;即使是低收入的玩法&#xff0c;一个月赚取万儿八千也是完全可行的。而高收入的玩法&#xff0c;一单的收入甚至能超过一万。目前&#xff0c;你的圈子里已经有一些同行业的人开始以个人工作室的形式去…

【机器学习】数学基础详解

线性代数&#xff1a;构建数据的骨架 数学对象 标量&#xff08;Scalar&#xff09; 标量是最基本的数学对象&#xff0c;代表了单个的数值&#xff0c;无论是整数还是实数。在机器学习中&#xff0c;标量可以用来表示一个模型的单个参数&#xff0c;如偏差&#xff08;bias&…

Collection与数据结构 Stack与Queue(二):队列与Queue

1. 队列 1.1 概念 只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出FIFO(First In First Out) 入队列&#xff1a;进行插入操作的一端称为队尾&#xff08;Tail/Rear&#xff09; 出队列&#xff1a;进行删除操作…

免费https详细教程

简单叙述一下https的定义和实现https的一些基本作用&#xff0c;然后会给到申请SSL证书的方式以及安装部署流程&#xff0c;最终实现网站的https访问。 随着互联网的快速发展&#xff0c;网络安全问题日益凸显。在互联网上传输敏感信息、进行在线交易和共享个人数据时&#xf…

09 Php学习:数组和排序

数组概念 在PHP中&#xff0c;数组是一种复合数据类型&#xff0c;用于存储多个值。以下是关于PHP数组的详细解释&#xff1a; 索引数组&#xff1a;索引数组是最基本的数组类型&#xff0c;其中每个元素都有一个唯一的数字索引&#xff0c;从0开始递增。 关联数组&#xff…

Qt for MCUs 2.7正式发布

本文翻译自&#xff1a;Qt for MCUs 2.7 released 原文作者&#xff1a;Qt Group高级产品经理Yoann Lopes 翻译&#xff1a;Macsen Wang Qt for MCUs的新版本已发布&#xff0c;为Qt Quick Ultralite引擎带来了新功能&#xff0c;增加了更多MCU平台的支持&#xff0c;并且我们…

概率论基础——拉格朗日乘数法

概率论基础——拉格朗日乘数法 概率论是机器学习和优化领域的重要基础之一&#xff0c;而拉格朗日乘数法与KKT条件是解决优化问题中约束条件的重要工具。本文将简单介绍拉格朗日乘数法的基本概念、应用以及如何用Python实现算法。 1. 基本概念 拉格朗日乘数法是一种用来求解…

Golang 开发实战day08 - Multiple Return values

&#x1f3c6;个人专栏 &#x1f93a; leetcode &#x1f9d7; Leetcode Prime &#x1f3c7; Golang20天教程 &#x1f6b4;‍♂️ Java问题收集园地 &#x1f334; 成长感悟 欢迎大家观看&#xff0c;不执着于追求顶峰&#xff0c;只享受探索过程 Golang 教程08 - Multiple R…

第⑬讲:OSD硬盘故障处理实战:从诊断到恢复的全流程指南

文章目录 1.OSD坏盘更换操作2.判断OSD是否出现故障的思路3.模拟osd.5故障4.OSD故障更换硬盘流程4.1.将故障的osd.5从集群中删除4.1.1.从OSD Map中将故障的OSD删除4.1.2.从Crush Map中将故障的OSD删除4.1.3.在OSD列表中将故障的OSD删除4.1.4.将故障的OSD认证信息删除4.1.5.验证集…

羊大师带你了解春季喝羊奶有什么好处

在春季&#xff0c;随着大自然的苏醒&#xff0c;人们的生活方式也逐渐转向更加活跃和健康的模式。在众多健康习惯中&#xff0c;饮用羊奶成为了一个流行的选择&#xff0c;因其独特的营养价值和健康益处受到了广泛关注。羊奶不仅富含高质量的蛋白质和必需氨基酸&#xff0c;还…