线程池的原理(高薪常问)
线程池的工作过程如下:
当一个任务提交至线程池之后,
1. 线程池首先判断核心线程池里的线程是否已经满了。如果不是,则创建一个新的工作线程来执行任务。否则进入 2.
2. 判断工作队列是否已经满了,倘若还没有满,将任务放入队列。否则进入 3.
3. 判断线程池里的线程是否都在执行任务。如果不是,则创建一个新的工作线程来执行。
如果线程池满了,则交给饱和策略来处理任务。
1.JDK自带的线程池有哪些?


2.线程池中核心线程数与最大线程数与缓冲任务队列的关系?
在Java中的线程池(如ThreadPoolExecutor)中,核心线程数(corePoolSize)、最大线程数(maximumPoolSize)以及缓冲队列(workQueue)之间存在着密切的关系,它们共同决定了线程池如何管理和调度任务。以下是它们之间的关系概述:
-
核心线程数 (corePoolSize):
-
核心线程是线程池中最基础的线程数,即使在没有任务执行时,也会一直存活在线程池中。
-
当提交新任务时,线程池首先尝试创建或保持至多corePoolSize个线程来处理任务(长工)。
-
最大线程数 (maximumPoolSize):
-
当核心线程数全部处于活动状态且仍有新任务提交时,线程池将创建额外的线程(临时工),直至线程总数达到maximumPoolSize。
-
当线程数达到maximumPoolSize时,线程池不会再创建新的线程,除非现有线程中有线程终止。
-
缓冲队列 (workQueue):
-
只要有任务,新提交的任务会被放入缓冲队列中等待执行,当有长工不忙的时候,长工领任务执行.
-
当所有核心线程都在忙,并且缓冲队列尚未满时,新提交的任务也会被放入队列中排队(等待长工去执行)。
-
若队列已满(即有界队列的情况),并且线程数未达到maximumPoolSize,线程池会创建新的非核心线程(临时工)来执行任务。
-
当线程数已经达到maximumPoolSize,而缓冲队列也已经满了,这时线程池将依据预先设定的拒绝策略来处理无法接受的任务,例如丢弃任务、抛出异常或调用用户自定义的拒绝处理器。
综上所述,线程池的工作机制是这样的:
-
先使用核心线程执行任务。
-
当核心线程不足时,新任务入队列等待。
-
当队列满且线程数未达最大值时,增加非核心线程执行任务。
-
当队列满且线程数已达最大值时,触发拒绝策略处理新来的任务。
3.为什么阿里巴巴不让使用JDK自带的线程池?
阿里巴巴在《阿里巴巴Java开发手册》中建议开发者不要直接使用 java.util.concurrent.Executors 类中的静态工厂方法来创建线程池,而是推荐直接使用 ThreadPoolExecutor 类来实例化线程池,主要原因如下:
-
资源耗尽的风险: JDK内置的
Executors工厂方法创建的线程池往往具有固定的配置,比如newFixedThreadPool创建的是固定大小线程池,newCachedThreadPool创建的是可无限扩大的线程池,这些配置可能并不适用于所有的场景。尤其像newCachedThreadPool,如果不加以控制,当任务量过大时,可能导致创建过多线程,进而耗尽系统资源(如内存),甚至引发 OutOfMemoryError 错误。 -
拒绝策略不明确:
Executors提供的预设线程池配置对拒绝策略的处理不够明确,开发者可能不清楚在任务堆积严重时,线程池具体是如何处理新提交的任务的。而直接使用ThreadPoolExecutor可以让开发者显式指定拒绝策略,对系统的稳定性和可控性有更好的把握。 -
线程池参数优化:
ThreadPoolExecutor允许自定义更多的参数,如线程存活时间、队列类型和大小等,这样可以根据实际应用场景调整线程池行为,使之更符合业务需求,提高性能并防止潜在的问题。 -
监控和调试难度: 自定义线程池可以更容易地集成到监控系统中,方便开发者随时观察线程池的状态,及时发现问题并进行调整。
总结起来,阿里巴巴之所以推荐使用 ThreadPoolExecutor 手动创建线程池,是为了增强系统稳定性,降低资源耗损风险,并提升开发者对线程池行为的控制能力。
三、核心参数(高薪常问)
corePoolSize:核心线程池的大小
maximumPoolSize:线程池能创建线程的最大个数
keepAliveTime:空闲线程存活时间
unit:时间单位,为 keepAliveTime 指定时间单位
workQueue:阻塞队列,用于保存任务的阻塞队列
threadFactory:创建线程的工程类
handler:饱和策略(拒绝策略)
本文详细阐述了线程池的工作原理,包括核心线程池、最大线程数、缓冲队列的协作,以及阿里巴巴为何推荐使用ThreadPoolExecutor而非JDK内置线程池。特别强调了自定义线程池的优势,如资源管理、明确的拒绝策略和性能优化。
150

被折叠的 条评论
为什么被折叠?



