JAVA并发编程之线程池参数

一文读懂线程池参数

面试过程中常问的线程池参数问题,你都掌握了吗?如果还没有,那么恭喜看到这篇文章的你。接下来就需要你花点时间,通过阅读文章,掌握线程池的各个参数。

线程池参数表

参数名 说明
corePoolSize the number of threads to keep in the pool 核心线程数
maximumPoolSize the maximum number of threads to allow in the pool 最大线程数
keepAliveTime when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating. 空闲线程存活时间
unit the time unit for the {@code keepAliveTime} argument 时间单位
workQueue the queue to use for holding tasks before they are executed. This queue will hold only the {@code Runnable} tasks submitted by the {@code execute} method. 用于存放任务的队列
threadFactory the factory to use when the executor creates a new thread 线程工厂,用于创建新线程
handler the handler to use when execution is blocked because the thread bounds and queue capacities are reached 处理被拒绝的任务

参数详细介绍

任务提交工作流程

JAVA并发编程之线程池参数_第1张图片

  1. 提交任务后,线程池首先会检查当前线程数,如果此时线程数小于核心线程数,则新建线程并执行任务,随着任务的不断增加,线程数会逐渐增加并达到核心线程数,此时如果仍有任务被不断提交,就会被放入 workQueue 任务队列中,等待核心线程执行完当前任务后重新从 workQueue 中提取正在等待被执行的任务。

  2. 当任务达到了 workQueue 的容量上限,这时线程池就会使用备用线程,也就是 maximumPoolSize 最大线程数,线程池会在 corePoolSize 核心线程数的基础上继续创建线程来执行任务,假设任务被不断提交,线程池会持续创建线程直到线程数达到 maximumPoolSize 最大线程数,如果依然有任务被提交,这就超过了线程池的最大处理能力,这个时候线程池就会拒绝这些任务,我们可以看到实际上任务进来之后,线程池会逐一判断 corePoolSize、workQueue、maximumPoolSize,如果依然不能满足需求,则会拒绝任务。


corePoolSize 与 maximumPoolSize

  • corePoolSize 核心线程数

    • 线程池初始化时线程数为 0,有新的任务提交后,会创建新的线程,直到线程数达到核心线程数。
    • 核心线程一般不会被销毁
  • maximumPoolSize 最大线程数

    • 随着任务量的增加,在任务队列满了之后,线程池会进一步创建新线程,最多可以达到 maximumPoolSize

    • 当线程有空闲时,大于 corePoolSize 的线程会被合理回收

所以正常情况下,线程池中的线程数量会控制在 corePoolSize 至 maximumPoolSize 之间。

keepAliveTime 与 unit

  • keepAliveTime

    • 当线程池中线程数大于核心线程数时,且处于空闲状态,线程池就会检测线程的 keepAliveTime,如果超过规定的时间,空闲的线程就会被销毁,以便减少内存的占用和资源消耗。
    • 通过setKeepAliveTime 方法,可以动态改变 keepAliveTime 的参数值
  • unit

    • 时间单位,配合 keepAliveTime 使用

ThreadFactory

  • ThreadFactory
    • 线程工厂,它的作用是生产线程以便执行任务。我们可以选择使用默认的线程工厂,创建的线程都会在同一个线程组,并拥有一样的优先级,且都不是守护线程,我们也可以选择自己定制线程工厂,以方便给线程自定义命名,不同的线程池内的线程通常会根据具体业务来定制不同的线程名。

workQueue 与 Handler

  • workQueue
    • 阻塞队列
  • Handler
    • 任务拒绝策略

线程池的特点

  • 线程池希望保持较少的线程数,并且只有在负载变得很大时才增加线程。

  • 线程池只有在任务队列填满时才创建多于 corePoolSize 的线程,如果使用的是无界队列(例如 LinkedBlockingQueue),那么由于队列不会满,所以线程数不会超过 corePoolSize。

  • 通过设置 corePoolSize 和 maximumPoolSize 为相同的值,就可以创建固定大小的线程池。

  • 通过设置 maximumPoolSize 为很高的值,例如 Integer.MAX_VALUE,就可以允许线程池创建任意多的线程

使用线程池的好处

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

你可能感兴趣的:(Java,java,面试,多线程)