线程池相关

news2024/11/16 9:46:35

文章目录

  • 为什么需要线程池?
  • 池化思想
  • 常用方法
    • execute()方法
    • submit()方法
    • shutdown
    • isShutdown
    • isTerminated
    • awaitTermination
    • shutdownNow
  • 创建线程池 七个参数
  • 流程
  • JAVA线程池有哪几种类型?
  • 线程池常用的阻塞队列有哪些?
  • 源码中线程池是怎么复用线程的?
  • 如何合理配置线程池参数?

————————————————————————————————

为什么需要线程池?

线程每次执行完之后会销毁,然后创建,新建线程

获取一个任务,销毁线程–标记为无效空间,然后在新建线程,再销毁线程(每个任务之间都有销毁和新建)

好处就是不会一直占据着空间和CPU

坏处就是需要一直新建销毁 浪费时间这样的时间的开销很大,

如何防止线程被销毁呢,线程设置死循环,不让线程执行完毕,这样线程就不会被销毁掉了

线程一直存活的话,如果一个任务运行完成可以直接执行下一个任务

流程:一直获取任务,不需要新建与销毁

缺点是:一直消耗着cpu 同时一直占着空间

池化思想

第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
第三:提高线程的可管理性。线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统-分配、调优和监控

常用方法

execute()方法

用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功与否:

​只能接收Runnable类型的参数,而Runnable类型的任务不可以返回执行结果

submit()方法

submit()方法可以接收Callable、Runnable两种类型的参数,Callable类型的任务作为Runnable的一种补充,允许有返回值,允许抛出异常

submit()方法自身并不会传递结果,而是返回一个future类型的对象,通过这个future对象可以判断任务是否执行成功,并且可以通过future的get(方法来获取返回值,get()方法会阻塞当前线程直到任务完成,调用Future.get()方法获取执行结果时,可以捕获异步执行过程中抛出的受检异常和运行时异常,并进行对应的业务处理。

shutdown

shutdown(),它可以安全地关闭一个线程池,调用 shutdown() 方法之后线程池并不是立刻就被关闭,因为这时线程池中可能还有很多任务正在被执行,或是任务队列中有大量正在等待被执行的任务,调用 shutdown() 方法后线程池会在执行完正在执行的任务和队列中等待的任务后才彻底关闭。

调用 shutdown() 方法后如果还有新的任务被提交,线程池则会根据拒绝策略直接拒绝后续新提交的任务。

isShutdown

第二个方法叫作 isShutdown(),它可以返回 true 或者 false 来判断线程池是否已经开始了关闭工作,也就是是否执行了 shutdown 或者 shutdownNow 方法。

这里需要注意,如果调用 isShutdown() 方法的返回的结果为 true 并不代表线程池此时已经彻底关闭了,这仅仅代表线程池开始了关闭的流程,也就是说,此时可能线程池中依然有线程在执行任务,队列里也可能有等待被执行的任务

isTerminated

这个方法可以检测线程池是否真正“终结”了,这不仅代表线程池已关闭,同时代表线程池中的所有任务都已经都执行完毕了。

比如我们上面提到的情况,如果此时已经调用了 shutdown 方法,但是还有任务没有执行完,那么此时调用 isShutdown 方法返回的是 true,而 isTerminated 方法则会返回 false。

直到所有任务都执行完毕了,调用 isTerminated() 方法才会返回 true,这表示线程池已关闭并且线程池内部是空的,所有剩余的任务都执行完毕了。

awaitTermination

主要用来判断线程池状态的。
比如我们给 awaitTermination 方法传入的参数是 10 秒,那么它就会陷入 10 秒钟的等待,直到发生以下三种情况之一:

  • 等待期间(包括进入等待状态之前)线程池已关闭并且所有已提交的任务(包括正在执行的和队列中等待的)都执行完毕,相当于线程池已经“终结”了,方法便会返回 true
  • 等待超时时间到后,第一种线程池“终结”的情况始终未发生,方法返回 false
  • 等待期间线程被中断,方法会抛出 InterruptedException 异常

调用 awaitTermination 方法后当前线程会尝试等待一段指定的时间,如果在等待时间内,线程池已关闭并且内部的任务都执行完毕了,也就是说线程池真正“终结”了,那么方法就返回 true,否则超时返回 fasle。

shutdownNow

shutdownNow(),它和 shutdown() 的区别就是多了一个 Now,表示立刻关闭的意思,不推荐使用这一种方式关闭线程池。

在执行 shutdownNow 方法之后,首先会给所有线程池中的线程发送 interrupt 中断信号,尝试中断这些任务的执行,然后会将任务队列中正在等待的所有任务转移到一个 List 中并返回,我们可以根据返回的任务 List 来进行一些补救的操作,例如记录在案并在后期重试。

shutdown 没有返回值,而 shutdownNow 会返回关闭前任务队列中未执行的任务集合(List)

创建线程池 七个参数

1、核心线程数,就是三个常用柜台
2、最大线程数,也就是最多五个窗口
3、存活时间,多久没有任务后线程就会停止
4、时间单位,
5、等待队列,三个等候区
6、线程工厂
7、 拒绝策略

流程

在这里插入图片描述
1、execute/submit方法向线程池添加任务,只要核心线程数没满,每次过来一个新任务,都会创建一个新线程

2.当任务大于核心线程数corePoolSize,就向阻塞队列添加任务。

3.如果阻塞队列已满,需要通过比较参数maximumPoolSize(最大线程数的作用就是加速消耗),在线程池创建新的线程,当线程数量大于maximumPoolSize(最大线程数),传输速度仍然大于所有线程执行任务的速度,说明当前设置线程池中线程已经处理不了了,就会执行拒绝策略。

但一段时间内没有提交任务,所有线程都会再次停止,然后重新开启那10个核心线程,因为如果不设置提交时间的话,一直开着这么多的线程对CPU来说是巨大的消耗

队列长度一定要是有界限的,这样才能触发最大线程数,加速任务的执行速度

JAVA线程池有哪几种类型?

1、ScheduledThreadPool:-------------DelayedWorkQueue
创建一个定长线程池,支持定时或周期性执行任务。比如每隔 10 秒钟执行一次任务

2、FixedThreadPool:可重用固定线程数的线程池-----------------LinkedBlockingQueue
它的核心线程数和最大线程数是一样的,所以可以把它看作是固定线程数的线程池,它的特点是线程池中的线程数除了初始阶段需要从 0 开始增加外,之后的线程数量就是固定的,就算任务数超过线程数,线程池也不会再创建更多的线程来处理任务,而是会把超出线程处理能力的任务放到任务队列中进行等待。而且就算任务队列满了,到了本该继续增加线程数的时候,由于它的最大线程数和核心线程数是一样的,所以也无法再增加新的线程了。

3、CachedThreadPool:可缓存的线程池 ----------SynchronousQueue
创建一个可缓存线程池,线程数是几乎可以无限增加的,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
有一个用于存储提交任务的队列,但这个队列是 SynchronousQueue,队列的容量为0,实际不存储任何任务,它只负责对任务进行中转和传递,所以效率比较高。当我们提交一个任务后,线程池会判断已创建的线程中是否有空闲线程,如果有空闲线程则将任务直接指派给空闲线程,如果没有空闲线程,则新建线程去执行任务,这样就做到了动态地新增线程

4、SingleThreadExecutor:只有一个线程的线程池 ----------LinkedBlockingQueue
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。 如果线程在执行任务的过程中发生异常,线程池也会重新创建一个线程来执行后续的任务。这种线程池由于只有一个线程,所以非常适合用于所有任务都需要按被提交的顺序依次执行的场景

5、threadPool = new ThreadPoolExecutor();
//默认线程池,可控制参数比较多

线程池常用的阻塞队列有哪些?

  1. LinkedBlockingQueue
    LinkedBlockingQueue这样一个没有 容量限制的阻塞队列来存放任务。
    这里需要注意,由于线程池的任务队列永远不会放满,所以线程池只会创建核心线程数量的线程,所以此时的最大线程数对线程池来说没有意义
  2. SynchronousQueue
  3. DelayedWorkQueue
    第三种阻塞队列是DelayedWorkQueue,这两种线程池的最大特点就是可以延迟执行任务,比如说一定
    时间后执行任务或是每隔-定的时间执行一次任务。

源码中线程池是怎么复用线程的?

源码中ThreadPoolExecutor中有个内置对象Worker,每个worker都是一个线程, worker线程数量和参数有关,每个worker 会while死循环从阻塞队列中取数据,通过置换worker中Runnable对象,运行其run方法起到线程置换的效果,这样做的好处是避免多线程频繁线程切换,提高程序运行性能。

如何合理配置线程池参数?

自定义线程池就需要我们自己配置最大线程数maximumPoolSize,为了高效的并发运行,这时需要看我们的业务是IO密集型还是CPU密集型。
CPU密集型
CPU密集的意思是该任务需要最大的运算,而没有阻塞,CPU-直全速运行。CPU密集任务只有在真正的多核CPU上才能得到加速(通过多线程)。而在单核CPU上,无论你开几个模拟的多线程该任务都不可能得到加速,因为CPU总的运算能力就那么多。
I0密集型
I0密集型,即该任务需要大量的I0,即大量的阻塞。在单线程上运行I0密集型的任务会导致大量的CPU运算能力浪费在等待。所以在IO密集型任务中使用多线程可以大大的加速程序运行,即使在单核CPU上这种加速主要就是利用了被浪费掉的阻塞时间。
10密集型时,大部分线程都阻塞,故需要多配制线程数。公式为:
CPU核数*2
CPU核数/(1-阻塞系数)阻塞系数在0.8~0.9之间
查看CPU核数:
Sys tem. out . print1n(Runtime . getRuntime () . availableProcessorsO);

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

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

相关文章

EMQX Cloud 自定义函数实现多种 IoT 数据形式的灵活转化

物联网场景中,各类设备终端的种类繁杂,所使用的通信协议各异,从而使得应用层的数据格式也各不相同。为了帮助用户实现统一数据格式,EMQX Cloud 最近推出了自定义函数功能:根据用户自定义的脚本对设备上报的数据进行预处…

上美股份在港交所上市:预计全年利润下滑,一叶子收入持续走低

12月22日,上海上美化妆品股份有限公司(HK:02145,下称“上美股份”)在港交所上市。本次上市,上美股份的发行价格为25.20港元/股,为此前发行区间的最低值。据此计算,上美股份的募资总额约为9.31亿…

CDH6.3.2集成Apache Atlas2.1.0

1 环境准备 1.1 CDH6.3.2 环境搭建 参考文档如下 Cloudera Manager安装CDH6教程-(一)虚拟环境安装配置 Cloudera Manager安装CDH6教程-(二)搭建Cloudera和CDH6 CM和CDH在安装的时候遇到的问题 CDH6.3.2 各组件版本 1.2 apa…

火爆“有机新消费”驶入酱油赛道 好记打造我国有机酱油行业领导品牌

根据观研报告网发布的《2022年中国有机酱油市场分析报告-市场竞争策略与发展动向前瞻》显示,有机酱油是指采用有机农作物为原料酿制的酱油。有机酱油含有浓郁的酱香和脂香,是一种不可多得的上等调味品,适合于蘸食,红烧&#xff0c…

以技术创新践行社会责任,欧科云链斩获界面新闻年度双项大奖

12月20日,欧科云链凭借在区块链技术领域的创新,与腾讯、宁德时代和埃森哲等各领域领先企业一同荣获“2022好公司行业领先大奖”。 12月21日,欧科云链以区块链科技之力积极践行社会责任,绽放商业向善的力量,与茅台、蚂蚁…

华为云Stack智能进化,三大举措赋能政企深度用云

【中国,深圳,2022年12月22日】今天,以“政企深度用云,释放数字生产力”为主题的华为云Stack战略暨新品发布会在线上举办,华为云围绕“让技术不难用、让场景变简单、让经验可复制”提出三大关键举措赋能政企迈向深度用云…

无线鼠标怎么连接电脑?2个方法,轻松学会

现在越来越多的小伙伴都喜欢使用无线鼠标。相比于有线鼠标,无线鼠标方便快捷,不会受到USB线的束缚。可是很多小伙伴买回无线鼠标,第一次使用的时候,却发现自己不知道怎么使用。无线鼠标怎么连接电脑?今天小编给大家带来…

对于转行Pyhon程序员,这些是我们需要知道的事情..

不知道从什么时候开始,我们焦虑当下,担心未来,踌躇和迷茫甚至痛苦成为我们的“生活伴侣”。 我无法定义这是好是坏,但我知道这肯定很难受。于是乎总很多人想寻得一个答案,希望可以抹平心中的波澜。而往往事与愿违。 …

口罩后,那些被“优化”的程序员都去哪儿了?

程序员在35岁真的会被裁吗? 被裁之后去哪儿工作 ,怎么办啊? 在很多社交平台,经常能看到不少小伙伴问出这样的问题,既迷茫,又慌张。有人说自己25岁就已经被裁了,也有人说做程序员,3…

江苏移动MGV3000-YS(S)/YS(M)-S905L3卡刷和线刷固件包

江苏移动MGV3000-YS(S)/YS(M)-S905L3卡刷和线刷固件包 固件特点: 1、修改dns,三网通用; 2、开放原厂固件屏蔽的市场安装和u盘安装apk; 3、无开机广告,无系统更新,不在被强制升级&#xff1b…

数据结构与算法java实战篇--链表

目录 一.链结点 二.单链表 1.单链表的插入方法insertFirst() 2.单链表的删除方法deleteFirst() 3.链表显示displayList() 4.单链表代码: 三. 查找和删除指定链结点 四.双端链表 五.用链表实现的栈 六.用链表实现队列 七.有序链表 八.双向链表 1.遍历 2.插入…

“量子深度学习的春天是否已来?” | CNCC论坛分享

2022年12月8日举办的CNCC2022“量子深度学习的春天是否已来?”技术论坛,从学术、技术和产业的角度出发,深入探讨未来5到10年深度学习发展在算力方面的瓶颈问题、量子深度学习会给AI领域带来何种演变以及量子深度学习的技术落地是否依然久远等…

代码随想录Day58|739. 每日温度、496.下一个更大元素 I

文章目录739.每日温度496.下一个更大元素 I739.每日温度 文章讲解:代码随想录 (programmercarl.com) 题目链接:739. 每日温度 - 力扣(LeetCode) 题目: 请根据每日 气温 列表,重新生成一个列表。对应位置…

weidl x DeepRec:热门微博推荐框架性能提升实战

微博推荐团队:陈雨、韩楠、蔡小娟、高家华 1.项目背景 热门微博是新浪微博的重要功能之一,包含热门流、热点流、频道流、小视频后推荐、视频社区等场景。 标推荐首页 发现页推荐 沉浸视频题weidl机器学习框架为热门微博在线学习提供模型训练和推理服务…

【问题记录与解决】ModuleNotFoundError: No module named ‘pymongo‘ 并测试代码

目录 一、问题记录二、解决方法一(不一定好使)三、法二(亲测可以使用)四、安装 pymongo 的目的一、问题记录 报错内容是缺少对应的模块, ModuleNotFoundError: No module named pymongo… 二、解决方法一(不一定好使) 直接在PyCharm中下载 pymongo模块即可。 但是这…

试卷安全分发系统

摘要 高校教务管理过程中,试卷以明文形式传输和集中存储,存在数据泄漏安全隐患。现提出了一个基于数字证书的试卷防泄漏方案,采用算法加密试卷,试卷在传输过程中中以密文的形式传输,每次传输的时候都会对试卷进行签名…

CadQuery二维Sketch教程

2D草图是3D CAD的基础。本文介绍如何在CadQuery中使用不同的方法构建二维草图(Sketch)。 1、基于面的 API 构建2D草图的主要方法是基于构建面并使用布尔运算将它们组合起来。 import cadquery as cqresult (cq.Sketch().trapezoid(4,3,90).vertices…

【GO】 K8s 管理系统项目[API部分--StatefulSet]

K8s 管理系统项目[API部分–StatefulSet] 1. 接口实现 service/dataselector.go // statefulSetCell type statefulSetCell appsv1.StatefulSetfunc(s statefulSetCell) GetCreation() time.Time {return s.CreationTimestamp.Time }func(s statefulSetCell) GetName() stri…

河道水文标尺监测系统 OpenCv

河道水文标尺监测系统借助PythonOpenCv深度学习架构模型对江河湖泊进行全天候不间断实时检测,当PythonOpenCv深度学习架构模型监测到水位异常时,立即抓拍存档告警,同步告警截图和视频推送给相关人员。OpenCV的全称是Open Source Computer Vis…

JUC之ABA问题

什么是ABA问题? ABA问题是由CAS而导致的一个问题 CAS算法实现一个重要前提需要取出内存中某时刻的数据并在当下时刻比较并交换,那么在这个时间差内会导致数据的变化。 比如说一个线程一从内存位置V中取出A,这是另一个线程二也从内存中取出…