【多线程:线程池】ThreadPoolExecutor类的基本概念

简介: 【多线程:线程池】ThreadPoolExecutor类的基本概念

【多线程:线程池】ThreadPoolExecutor类的基本概念

01.介绍


ThreadPoolExecutor类实现了ExecutorService接口,他与ScheduledThreadPoolExecutor类的不同是ScheduledThreadPoolExecutor是带有任务调度功能的线程池实现 这个我们之后再讲。

02.ThreadPoolExecutor-池状态

ThreadPoolExecutor使用int的高3位来表示线程池状态,第29位表示线程数量

状态名 高3位 接收新任务 处理阻塞队列任务 说明
RUNNING 111 Y Y
SHUTDOWN 000 N Y 不会接收新任务,但会处理阻塞队列剩余任务
STOP 001 会中断正在执行的任务,并抛弃阻塞队列任务
TIDYING 010 任务全执行完毕,活动线程为0即将进入终结
TERMINAIED 011 终结状态

为什么线程池状态与线程池数量要用一个数字表示,而不用两个数字,原因是这两个信息存储在一个原子变量ctl中,这样以后就可以只用一次cas原子操作进行赋值。

03.构造方法


我们可以看到ThreadPoolExecutor类的构造方法有很多参数,我们一个一个解释
corePoolSize:核心线程数目
maximumPoolSize:最大线程数目
keepAliveTime:生存时间-针对急救线程
unit:时间单位-针对救急线程
workQueue:阻塞队列
threaFactory:线程工厂-可以为线程创建时起名
hander:拒绝策略

ThreadPoolExecutor与我们自定义线程池的区别

  1. 救急我们自定义线程池,线程池中只有一种线程就是核心线程,且我们的核心线程有take方法与pull方法。但ThreadPoolExecutor线程池有两种线程 一种是核心线程 数量时corePoolSize,一种是救急线程 数量是maximumPoolSize-corePoolSize,且核心线程只有take方法 救急线程只有pull方法,这就是为什么keepAlivTime与unit只针对救急线程。
  2. 自定义线程池不能规定线程池中线程的名字,ThreadPoolExecutor线程池则可以通过threaFactory参数改变线程的名字
  3. 自定义线程池与ThreadPoolExecutor线程池的拒绝策略

工作方式

介绍

我们知道自定义线程池中只有核心线程,所以自定义线程池的流程是
创建任务->交给空闲的核心线程执行->超出部分的任务放入任务队列->如果此时有空闲核心线程则从任务队列里获取任务执行->如果没有空闲线程 且任务队列也满了->生产线程执行拒绝策略
ThreadPoolExecutor线程池中有核心线程与救急线程,所以ThreadPoolExecutor线程池的流程是
补充:ThreadPoolExecutor线程池的核心线程没有超时时间,救急线程有。
创建任务->交给空闲核心线程执行->超出部分的任务放入任务队列->如果此时有空闲核心线程->如果此时有空闲核心线程则从任务队列里获取任务执行交给核心的->如果没有空闲线程 且任务队列也满了->创建救急线程 多出的任务交给救急线程执行->如果救急线程也没有空闲了->生产线程执行拒绝策略

解释

可以看出救急线程的作用是在核心线程与任务队列都满的情况下 创建救急线程 如果救急线程在超时时间内没有获取到任务则从线程池中移除。

拒绝策略

如果核心线程没有空闲 任务队列满了 救急线程没有空闲,在这种情况下执行拒绝策略,拒绝策略jdk提供了四种实现。

  1. AbortPolicy 让调用者抛出 RejectedExecutionException 异常,这是默认策略
  2. CallerRunsPolicy 让调用者运行任务
  3. DiscardPolicy 放弃本次任务
  4. DiscardOldestPolicy 放弃队列中最早的任务,本任务取而代之
目录
打赏
0
0
0
0
1
分享
相关文章
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
在计算机系统的底层架构中,操作系统肩负着资源管理与任务调度的重任。当我们启动各类应用程序时,其背后复杂的运作机制便悄然展开。程序,作为静态的指令集合,如何在系统中实现动态执行?本文带你一探究竟!
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
|
3月前
|
【Java并发】【线程池】带你从0-1入门线程池
欢迎来到我的技术博客!我是一名热爱编程的开发者,梦想是编写高端CRUD应用。2025年我正在沉淀中,博客更新速度加快,期待与你一起成长。 线程池是一种复用线程资源的机制,通过预先创建一定数量的线程并管理其生命周期,避免频繁创建/销毁线程带来的性能开销。它解决了线程创建成本高、资源耗尽风险、响应速度慢和任务执行缺乏管理等问题。
226 60
【Java并发】【线程池】带你从0-1入门线程池
|
13天前
|
线程池是什么?线程池在实际工作中的应用
总的来说,线程池是一种有效的多线程处理方式,它可以提高系统的性能和稳定性。在实际工作中,我们需要根据任务的特性和系统的硬件能力来合理设置线程池的大小,以达到最佳的效果。
42 18
|
3月前
|
python3多线程中使用线程睡眠
本文详细介绍了Python3多线程编程中使用线程睡眠的基本方法和应用场景。通过 `time.sleep()`函数,可以使线程暂停执行一段指定的时间,从而控制线程的执行节奏。通过实际示例演示了如何在多线程中使用线程睡眠来实现计数器和下载器功能。希望本文能帮助您更好地理解和应用Python多线程编程,提高程序的并发能力和执行效率。
88 20
|
2月前
|
【源码】【Java并发】【线程池】邀请您从0-1阅读ThreadPoolExecutor源码
当我们创建一个`ThreadPoolExecutor`的时候,你是否会好奇🤔,它到底发生了什么?比如:我传的拒绝策略、线程工厂是啥时候被使用的? 核心线程数是个啥?最大线程数和它又有什么关系?线程池,它是怎么调度,我们传入的线程?...不要着急,小手手点上关注、点赞、收藏。主播马上从源码的角度带你们探索神秘线程池的世界...
179 0
【源码】【Java并发】【线程池】邀请您从0-1阅读ThreadPoolExecutor源码
Unity多线程使用(线程池)
在C#中使用线程池需引用`System.Threading`。创建单个线程时,务必在Unity程序停止前关闭线程(如使用`Thread.Abort()`),否则可能导致崩溃。示例代码展示了如何创建和管理线程,确保在线程中执行任务并在主线程中处理结果。完整代码包括线程池队列、主线程检查及线程安全的操作队列管理,确保多线程操作的稳定性和安全性。
|
3月前
|
Linux编程: 在业务线程中注册和处理Linux信号
本文详细介绍了如何在Linux中通过在业务线程中注册和处理信号。我们讨论了信号的基本概念,并通过完整的代码示例展示了在业务线程中注册和处理信号的方法。通过正确地使用信号处理机制,可以提高程序的健壮性和响应能力。希望本文能帮助您更好地理解和应用Linux信号处理,提高开发效率和代码质量。
72 17
|
3月前
|
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
71 26
|
5月前
|
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
396 2
Java多线程编程的陷阱与解决方案####
本文深入探讨了Java多线程编程中常见的问题及其解决策略。通过分析竞态条件、死锁、活锁等典型场景,并结合代码示例和实用技巧,帮助开发者有效避免这些陷阱,提升并发程序的稳定性和性能。 ####
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等