当前位置: 首页 > news >正文

线程池的执行流程和配置参数总结

一、线程池的执行流程总结

  • 提交线程任务;
  • 如果线程池中存在空闲线程,则分配一个空闲线程给任务,执行线程任务;
  • 线程池中不存在空闲线程,则线程池会判断当前线程数是否超过核心线程数(corePoolSize)
    • 若未超出核心线程数,则创建一个核心线程用来执行线程任务;
    • 若超出核心线程数,则线程池会检查工作队列(workQueue)是否已满
      • 如果工作队列未满,则将该线程任务存入工作队列中,当线程池中出现空闲线程,从工作队列中依次取出线程任务并执行;
      • 如果工作队列已满,则判断是否超出最大线程数(maximumPoolSize)
        • 若当前线程池中的线程数超出最大线程数,则执行拒绝策略(defaultHandler)
        • 若当前线程池中的线程数未超出最大线程数,则创建非核心线程数来执行线程任务。

二、线程池的配置参数总结

1.核心线程数:corePoolSize

int corePoolSize

核心线程数也就是线程池的最小线程数量。

  • 核心线程会一直存活,不会被回收,除非设置了核心线程超时时间;
  • 在创建线程池后,默认情况下,线程池中没有任何线程,调用excute()方法添加一个任务。

当线程池中没有空闲线程时,查看是否超过核心线程数:

  • 线程数量小于核心线程数,则马上创建新的核心线程来执行线程任务。
  • 线程数量大于核心线程数,则查看工作队列是否超出。
2.最大线程数:maximumPoolSize

int maximumPoolSize

是指线程池中允许的最大线程数量。

当工作队列已满,且存活线程数超过了核心线程数时,线程池判断“存活线程数”是否超过最大线程数:

  • 未超过最大线程数:创建新线程来执行该任务。
  • 超过最大线程数:执行拒绝策略。
3.非核心的空闲线程的存活时间:keepAliveTime

long keepAliveTime

当线程数大于核心线程数时,空闲的线程等待新任务到达的最大时间,如果超过这个时间线程还没有需要执行的任务,该空闲线程就会销毁。

4.keepAliveTime的单位:unit

TimeUnit unit

keepAliveTime的单位,枚举类型的TimeUnit类。

5.阻塞工作队列:workQueue

BlockingQueue<Runnable> workQueue

在任务执行之前,用来存储任务的工作队列,此队列只保存由excute()方法提交的Runnable类型的任务。

当存活的线程数大于核心线程数,查看工作队列:

  • 工作队列未满:将新的请求任务加入工作队列;
  • 工作队列已满:线程池判断是否超过最大线程数。
5.1 ArrayBlockingQueue

基于数组有界阻塞队列,FIFO(先进先出)。

  • capacity:队列初始化大小
  • fair:表示该队列中的可重入锁是否公平,默认为false

当线程池中已经存在最大数量的线程时候,再请求新的任务,这时就会将任务加入工作队列的队尾,一旦有空闲线程,就会取出队头执行任务。

5.2 LinkedBlockingQueue

基于链表的误解阻塞队列,默认最大容量为Integer.MAX_VALUE,可认为是无限队列,FIFO(先进先出)。

指定工作队列大小,则最大线程数量的限制是有效的。

5.3 SynchronousQueue

可以将SynchronousQueue看作是一个没有容量的阻塞队列,它严格遵循FIFO(先进先出)的原则,但特殊的是,它不会保存任何元素,而是直接在不同的线程间进行传递。

6.线程工厂:threadFactory

ThreadFactory threadFactory

用于创建一个新线程时使用的工厂,可以用来设置线程名。

没有特别声明时,使用Executors工具类提供的默认线程工Executors.defaultThreadFactory()

自定义线程工厂时,要实现ThreadFactory接口,重写newThread()方法。

7.拒绝策略:handler

RejectedExecutionHandler handler

当线程池内的线程被耗尽,并且工作队列已满,对于新提交的任务,将使用拒绝策略进行处理。

7.1 AbortPolicy:丢弃线程任务,并抛出异常

没有特别声明时,使用默认的拒绝策略defaultHandler

7.2 DiscardOldestPolicy:将工作队列的对头移除,线程池重新执行该线程任务

7.3 DiscardPolicy:直接丢弃该任务

7.4 CallerRunPolicy:线程池没有关闭时,线程自己调用run方法

7.5 自定义的拒绝策略:实现RejectedExecutionHandler接口

重写void rejectedExecution(Runnable r, ThreadPoolExecutor executor)方法

相关文章:

  • np.array_fancy_indexing花式索引
  • Vue.js入门
  • 如何使用ssm实现基于BS的库存管理软件设计与实现+vue
  • AI中医香方仪丨OPENAIGC开发者大赛企业组AI创作力奖
  • 大数据新视界 --大数据大厂之数据清洗工具 OpenRefine 实战:清理与转换数据
  • tcp、udp通信调试工具Socket Tool
  • Android Perfetto 学习
  • 行情叠加量化,占据市场先机!
  • 嵌入式C语言自我修养:GNU C编译器扩展语法精讲
  • 那年我双手插兜,使用IPv6+DDNS动态域名解析访问NAS
  • MySQL数据库(基础)
  • 数据库 - MySQL的事务
  • STL之vector篇(下)(手撕底层代码,从零实现vector的常用指令,深度剖析并优化其核心代码)
  • 目标检测——VOC2007数据集
  • redis哨兵启动出现 +sdown master mymaster 192.168.x.x
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • JavaScript 基础知识 - 入门篇(一)
  • TypeScript迭代器
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 从0到1:PostCSS 插件开发最佳实践
  • 当SetTimeout遇到了字符串
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 什么是Javascript函数节流?
  • 数据结构java版之冒泡排序及优化
  • 《码出高效》学习笔记与书中错误记录
  • Hibernate主键生成策略及选择
  • Nginx实现动静分离
  • 阿里云服务器购买完整流程
  • 资深实践篇 | 基于Kubernetes 1.61的Kubernetes Scheduler 调度详解 ...
  • ​html.parser --- 简单的 HTML 和 XHTML 解析器​
  • ​io --- 处理流的核心工具​
  • (1)(1.13) SiK无线电高级配置(六)
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (不用互三)AI绘画:科技赋能艺术的崭新时代
  • (多级缓存)缓存同步
  • (二)JAVA使用POI操作excel
  • (七)c52学习之旅-中断
  • (七)理解angular中的module和injector,即依赖注入
  • (区间dp) (经典例题) 石子合并
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (一)u-boot-nand.bin的下载
  • (转)【Hibernate总结系列】使用举例
  • (转)ORM
  • (转)总结使用Unity 3D优化游戏运行性能的经验
  • (总结)(2)编译ORB_SLAM2遇到的错误
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • .net core 管理用户机密
  • .NET/C# 推荐一个我设计的缓存类型(适合缓存反射等耗性能的操作,附用法)
  • .net后端程序发布到nignx上,通过nginx访问
  • .NET学习全景图
  • .net之微信企业号开发(一) 所使用的环境与工具以及准备工作