基于本文回答

播面 播面

文图音视,全方位拆解八股文
0
评论

ThreadPoolExecutor 的七个核心构造参数分别是什么?

知识点图片

Java 中 ThreadPoolExecutor 的七个核心构造参数是理解和使用 Java 线程池的关键,这也是 Java 面试中极其高频的考点。

以下是这七个核心参数的详细解释:

1. corePoolSize(核心线程数)

  • 含义:线程池中长期维持的、即使处于空闲状态也不会被销毁的线程数量(除非设置了 allowCoreThreadTimeOut = true)。
  • 作用:当有新任务提交时,如果当前运行的线程数小于 corePoolSize,线程池会创建一个新线程来执行任务,即使池中有其他空闲的核心线程。

2. maximumPoolSize(最大线程数)

  • 含义:线程池允许创建的最大线程数量。
  • 作用:当核心线程数已满,并且工作队列(workQueue)也已经满了的情况下,如果还有新任务提交,线程池就会继续创建新的非核心线程来处理任务,直到线程总数达到 maximumPoolSize

3. keepAliveTime(空闲线程存活时间)

  • 含义:当线程池中的线程数量超过 corePoolSize 时,这些多余的空闲线程(非核心线程)在被销毁之前等待新任务的最长时间。
  • 作用:用于控制非核心线程的生命周期,避免系统资源的浪费。

4. unit(时间单位)

  • 含义keepAliveTime 参数的时间单位。
  • 常用值TimeUnit.SECONDS(秒)、TimeUnit.MILLISECONDS(毫秒)、TimeUnit.MINUTES(分钟)等。

5. workQueue(工作/任务队列)

  • 含义:用于保存等待执行的任务的阻塞队列。
  • 作用:当所有核心线程都在工作时,新提交的任务会被放入这个队列中排队等待。常见的队列有:
    • ArrayBlockingQueue:基于数组的有界阻塞队列。
    • LinkedBlockingQueue:基于链表的阻塞队列(默认容量为 Integer.MAX_VALUE,常被称为无界队列,但强烈建议指定容量)。
    • SynchronousQueue:不存储元素的阻塞队列(每个插入操作必须等待另一个线程的移除操作),通常配合较大的最大线程数使用(如 CachedThreadPool)。
    • PriorityBlockingQueue:具有优先级的无界阻塞队列。

6. threadFactory(线程工厂)

  • 含义:用于创建新线程的工厂。
  • 作用:通过自定义线程工厂,可以给线程池中的线程设置有意义的名字、设置是否为守护线程、设置线程优先级等。这在排查线上问题(如打印日志、查看 Dump 文件)时非常有用。默认使用 Executors.defaultThreadFactory()

7. handler(拒绝策略/饱和策略)

  • 含义:当线程池和工作队列都已经达到上限(即线程数等于 maximumPoolSizeworkQueue 已满),无法再接受新任务时,所采取的处理策略。
  • 内置的四种策略
    1. AbortPolicy(默认):直接抛出 RejectedExecutionException 异常,阻止系统正常运行。
    2. CallerRunsPolicy:将任务回退给调用者,由提交任务的当前线程(通常是主线程)来直接执行该任务。这会降低新任务的提交速度。
    3. DiscardPolicy:直接静默丢弃新提交的任务,不抛出异常。
    4. DiscardOldestPolicy:丢弃队列中最老的一个任务(即排在队首、马上要被执行的任务),然后尝试重新提交当前任务。

💡 核心参数的联动执行流程(重要)

为了彻底掌握这 7 个参数,必须理解它们是如何配合工作的。当一个新任务提交到线程池时,处理流程如下:

  1. 判断核心线程:如果当前运行的线程数 < corePoolSize,立即创建新线程执行任务。
  2. 判断工作队列:如果当前运行的线程数 >= corePoolSize,将任务放入 workQueue 中等待。
  3. 判断最大线程数:如果 workQueue 已满,且当前运行的线程数 < maximumPoolSize,创建非核心线程执行任务。
  4. 执行拒绝策略:如果 workQueue 已满,且运行的线程数 >= maximumPoolSize,则触发 handler(拒绝策略)处理该任务。
00:00
00:00