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

Java中的线程池参数(详解)

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {}

此构造方法的参数如下:

  1. int corePoolSize:核心线程数(正式员工人数)==正常情况下,我们的系统应该能同时工作的线程数(随时就绪的状态),线程池中一直存在的线程数,即使线程闲置。

  2. int maximumPoolSize:(最大线程数 => 哪怕任务再多,你也只能最多招5个人)==>极限情况下,我们的线程池最多有多少个线程?==>线程池中允许存在的最大线程数。

  3. long keepAliveTime:(空闲线程存活时间),非核心线程在没有任务的情况下,过多久要删除(理解为开除临时工),从而释放无用的线程资源。非核心线程的空闲线程存活时间,单位:毫秒。

  4. TimeUnit unit:(空闲线程存活时间的单位)存活时间的单位,可选的单位包括:TimeUnit.MILLISECONDS、TimeUnit.SECONDS、TimeUnit.MINUTES、TimeUnit.HOURS、TimeUnit.DAYS(时分秒)等等。

  5. BlockingQueue<Runnable> workQueue:(工作队列)用于存放给线程执行的任务,存在一个队列的长度(一定要设置,不要说队列长度无限,因为也会占用资源)。

    用于存放线程任务的阻塞队列,当线程池中的线程数达到了corePoolSize,而阻塞队列中任务满了时,线程池会创建新的线程(临时工),直到达到maximumPoolSize,此时达到线程池最大容量,若阻塞队列不为空,新加入的任务将会被拒绝,同时也可以通过设置RejectedExecutionHandler处理满了阻塞队列和饱和的情况。

    类型

    • SynchronousQueue: 不存储任务,直接将任务提交给线程。

    • LinkedBlockingQueue: 链表结构的阻塞队列,大小无限。

    • ArrayBlockingQueue: 数组结构的有界阻塞队列。

    • PriorityBlockingQueue: 带优先级的无界阻塞队列,总是返回优先级最高的元素。

  6. ThreadFactory threadFactory:(线程工厂)线程创建工厂,==>控制每个线程的生成、线程的属性(比如线程名)==>用于创建新的线程,可以自定义ThreadFactory。

  7. RejectedExecutionHandler handler:(拒绝策略)线程池拒绝策略,任务队列满的时候,我们采取什么措施,比如抛异常、不抛异常、自定义策略。

    当任务无法处理时,会根据设置的拒绝策略进行处理,可选的策略有:AbortPolicy(直接抛出异常,终止程序的执行)、CallerRunsPolicy(让当前的线程来处理该任务)、DiscardPolicy(直接丢弃该任务),DiscardOldestPolicy(丢弃队列中已经存在最久的任务,将当前任务插入队列尝试提交)。

    延伸讲解:

    资源隔离策略:不同的程度的任务,分为不同的队列,比如VIP一个队列,普通用户一个队列。

    线程池处理流程(重点)
    1. 在创建了线程池之后,等待提交过来的任务请求

    2. 当调用execute()方法添加一个请求任务的时候,线程池会做出如下判断:

      1. 如果正在运行的线程数量 < corePoolSize,即使线程池中已经有空闲核心线程,那么也会马上创建新的核心线程运行这个任务

      2. 如果正在运行的线程数量 >= corePoolSize,那么将这个任务放入队列

        1. 如果队列满了 并且正在运行的线程数量还 < maximumPoolSize,那么触发创建<临时线程> 立马(放在任务队列外)执行这个任务

        2. 一旦临时线程创建,在其存活时间内只要队列中有任务等待执行,临时线程就会继续执行这些任务(功能==核心线程)

        3. 如果队列满了并且正在运行的线程数量 >= maximumPoolSize,那么线程池会启动饱和拒绝策略来执行

      3. 如果线程数已到达最大,队列还没满,任务依然会进入队列,等待空闲线程处理

    3. 当一个线程完成任务的时候,它会从队列中取下一个空闲任务来执行,如果队列为空,则线程可能进入等待状态,直到有新任务到来

    4. 当一个线程无事可做超过一定时间(keepAliveTime)时:线程会判断如果当前运行的线程数大于corePoolSize,那么这个临时线程就会被停掉

    5. 核心线程和临时线程在执行任务时是平等的,只是核心线程,通常不会因闲置而被销毁

    补充知识:任务的分类

    任务分为IO密集型和计算密集型 是指任务所涉及的操作类型不同。

  8. IO密集型:任务需要大量的输入输出操作(I/O),如读取文件、访问数据库、网络通信等,这些操作的执行时间比较长,CPU 等待 IO 的时间比较多,CPU 利用率比较低。

  9. 计算密集型:任务需要大量的计算操作,如图像处理、视频编码、加密解密等,这些操作的执行时间比较短,CPU利用率比较高。

  10. 对于 IO 密集型任务,我们可以采用并发或异步方式来优化执行效率,并且可以采用缓存技术来避免频繁的 IO 操作;

  11. 对于计算密集型任务,我们可以采用多线程、分布式或 GPU 加速等方式来提高执行效率。


http://www.kler.cn/a/527167.html

相关文章:

  • 数据结构-Stack和栈
  • 表格结构标签
  • C#面试常考随笔4:int? 和 int的区别,以及int?的运用场景?
  • openssl 生成证书 windows导入证书
  • C# 9.0记录类型:解锁开发效率的魔法密码
  • Mac Electron 应用签名(signature)和公证(notarization)
  • Python 学习进阶技术文档
  • Keepalived高可用集群入门学习
  • electron 应用开发实践
  • Android逆向(Mitmproxy)
  • 【自学笔记】JavaWeb的重点知识点-持续更新
  • Oracle11g数据库安装及建库教程
  • JavaScript 创建对象的8种方式?
  • Git进阶之旅:tag 标签 IDEA 整合 Git
  • 算法总结-数组/字符串
  • Linux 五种IO模型总篇(阻塞IO、非阻塞IO、信号驱动IO、多路复用IO(select、poll、epoll)、异步IO)
  • 仿真设计|基于51单片机的温湿度及甲醛检测报警系统
  • OPENPPP2 —— VMUX_NET 多路复用原理剖析
  • DeepSeek R1功能设计涉及的几个关键词
  • 数据分析系列--⑥RapidMiner构建决策树(泰坦尼克号案例含数据)
  • Spring Boot基本项目结构
  • sizeof和strlen的对比与一些杂记
  • 【multi-agent-system】ubuntu24.04 安装uv python包管理器及安装依赖
  • Windows程序设计10:文件指针及目录的创建与删除
  • 【协议详解】卫星通信5G IoT NTN SIB33-NB 信令详解
  • CSS 图像、媒体和表单元素的样式化指南