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

Java线程池运行流程、配置参数及线程池类型

线程池的运行过程



线程池的配置参数


● corePoolSize线程池核心线程数:也可以理解为线程池维护的最小线程数量,核心线程创建后不会被回收。大于核心线程数的线程,在空闲时间超过keepAliveTime后会被回收;
        ○ 在创建了线程池后,默认情况下,线程池中并没有任何线程,当调用 execute() 方法添加一个任务时,如果正在运行的线程数量小于corePoolSize,则马上创建新线程并运行这个任务。
        ○ IO密集计算:由于 I/O 设备的速度相对于 CPU来说都很慢,所以大部分情况下,I/O 操作执行的时间相对于 CPU 计算来说都非常长,这种场景我们一般都称为 I/O 密集型计算。最佳线程数 =CPU 核数 * [ 1 +(I/O 耗时 / CPU 耗时)]。
        ○ CPU密集型:CPU 密集型计算大部分场景下都是纯 CPU 计算,多线程主要目的是提升CPU利用率,最佳线程数 =“CPU 核心数 +1”。这样的话,当线程因为偶尔的内存页失效或其他原因导致阻塞时,这个额外的线程可以临时替补,从而保证 CPU 的利用率。
● maximumPoolSize线程池最大线程数:线程池允许创建的最大线程数量;(包含核心线程池数量)
● keepAliveTime非核心线程线程存活时间:当一个可被回收的线程的空闲时间大于keepAliveTime,就会被回收。
        ○ 当线程池中的线程数大于corePoolSize时,如果一个线程空闲的时间达到keepAliveTime,则会被回收,直到线程池中的线程数不超过corePoolSize。
        ○ 如果设置allowCoreThreadTimeOut = true,在线程池中的线程数不大于corePoolSize时,keepAliveTime参数也会起作用,直到线程池中的线程数为0;
● TimeUnit时间单位:参数keepAliveTime的时间单位;
● BlockingQueue阻塞工作队列:用来存储等待执行的任务;
● ThreadFactory线程工厂 : 用于创建线程,以及自定义线程名称,需要实现ThreadFactory接口;
● RejectedExecutionHandler拒绝策略:当线程池线程内的线程耗尽,并且工作队列达到已满时,新提交的任务,将使用拒绝策略进行处理;
        ○ ThreadPoolExecutor.AbortPolicy:默认策略,丢弃任务并抛出RejectedExecutionException异常;
        ○ ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常;
        ○ ThreadPoolExecutor.DiscardOldestPolicy:丢弃工作队列中的队头任务(即最旧的任务,也就是最早进入队列的任务)后,继续将当前任务提交给线程池;
        ○ThreadPoolExecutor.CallerRunsPolicy:由原调用线程处理该任务 (谁调用,谁处理);

线程池类型总结

FixedThreadPool

线程数固定的线程池
● 线程池参数:
        ○ 核心线程数和最大线程数一致
        ○ 非核心线程线程空闲存活时间,即keepAliveTime为0
        ○ 阻塞队列为无界队列LinkedBlockingQueue
● 工作机制:
        ○ a提交线程任务
        ○ b如果线程数少于核心线程,创建核心线程执行任务
        ○ c如果线程数等于核心线程,把任务添加到LinkedBlockingQueue阻塞队列
        ○ d如果线程执行完任务,去阻塞队列取任务,继续执行
● 使用场景: 适用于处理CPU密集型的任务,确保CPU在长期被工作线程使用的情况下,尽可能的少的分配线程,即适用执行长期的任务。


CachedThreadPool

可缓存线程池,线程数根据任务动态调整的线程池
● 线程池参数:
        ○ 核心线程数为0
        ○ 最大线程数为Integer.MAX_VALUE
        ○ 工作队列是SynchronousQueue同步队列
        ○ 非核心线程空闲存活时间为60秒
● 工作机制:
        ○ a提交线程任务
        ○ b因为核心线程数为0,所以任务直接加到SynchronousQueue工作队列
        ○ c判断是否有空闲线程,如果有,就去取出任务执行
        ○ d如果没有空闲线程,就新建一个线程执行
        ○ e执行完任务的线程,还可以存活60秒,如果在这期间,接到任务,可以继续存活下去;否则,被销毁。
● 使用场景: 用于并发执行大量短期的小任务。


SingleThreadExecutor

单线程化的线程池
● 线程池参数:
        ○ 核心线程数为1
        ○ 最大线程数也为1
        ○ 阻塞队列是LinkedBlockingQueue 
        ○ 非核心线程空闲存活时间为0秒
● 使用场景: 适用于串行执行任务的场景,将任务按顺序执行。


ScheduledThreadPool

能实现定时、周期性任务的线程池
● 线程池参数:
        ○ 最大线程数为Integer.MAX_VALUE
        ○ 阻塞队列是DelayedWorkQueue 
        ○ keepAliveTime为0
● 使用场景: 周期性执行任务,并且需要限制线程数量的需求场景。  


http://www.mrgr.cn/news/30090.html

相关文章:

  • MATLAB系列08:输入/输入函数
  • 江协科技STM32学习- P13 TIM定时器中断
  • 探秘Python中的链表:从零开始的奇妙之旅
  • JAVA惊喜连连无限可能沉浸式盲盒商城系统小程序源码
  • 代码随想录 -- 二叉树 -- 删除二叉搜索树中的节点
  • 工单管理软件的优势有哪些?企业如何选择?
  • 【每日一诗】【诗词创作】【诗】《雨前秋夜》
  • 大模型学习起步的经验分享
  • Agile Modbus STM32裸机移植 从机使用
  • 图解Transformer工作原理(非常详细)零基础入门到精通,收藏这一篇就够了
  • C++ 面试模拟02
  • Mac 上哪个剪切板增强工具比较好用? 好用剪切板工具推荐
  • 二叉树的遍历【C++】
  • 土壤墒情测定仪的工作原理
  • layui table中的checkbox禁用问题
  • 再看Java-笔试
  • 为什么嫁人就要嫁公务员?稳定、收入高、福利好、资源多
  • 【技术解析】消息中间件MQ:从原理到RabbitMQ实战(深入浅出)
  • ICL、CoT、ReAct个人记录
  • js中两种异步方式:async+await以及then