线程池(Thread Pool)是一种管理和复用线程的机制,它在多线程编程中被广泛使用,主要目的是提高线程的利用率和性能,减少线程创建和销毁的开销。线程池的执行流程通常包括提交任务、判断当前存活线程数是否小于核心线程数、判断工作队列是否已满、判断当前存活线程数是否达到最大线程数、任务执行与线程回收几个步骤;
一、线程池执行流程
1、提交任务
当出现一个新的线程任务时,线程池会尝试分配一个空闲线程来执行该任务。
2、判断当前存活线程数是否小于核心线程数
如果线程池中不存在空闲线程,则线程池会判断当前“存活线程数”是否小于核心线程数;
小于核心线程数:如果当前存活线程数小于核心线程数(corePoolSize),线程池会创建一个新的核心线程,用来处理新任务。
大于核心线程数:如果当前存活线程数大于核心线程数,线程池会进入下一步判断。
3、判断工作队列是否已满
未满:如果工作队列(用于存储等待执行的任务)未满,线程池会将新任务放入工作队列中等待,等线程池中出现空闲线程时,再按照“先进先出”的规则分配执行。
已满:如果工作队列已满,线程池会进入下一步判断。
4、判断当前存活线程数是否达到最大线程数
小于最大线程数:如果当前存活线程数小于最大线程数(maximumPoolSize),线程池会创建一个新的非核心线程来执行新任务。
等于或大于最大线程数:如果当前存活线程数已经达到或超过最大线程数,线程池会采用拒绝策略来处理新任务。
二、常见的拒绝策略
AbortPolicy:直接抛出RejectedExecutionException异常,阻止系统正常运行(默认策略)。
CallerRunsPolicy:用调用者所在线程来执行任务,不会抛出异常。
DiscardPolicy:不处理该任务,直接丢弃掉。
DiscardOldestPolicy:丢弃最老的未处理的任务请求。
自定义拒绝策略:实现RejectedExecutionHandler接口,自定义任务被拒绝时的处理逻辑。
三、线程池的状态
线程池的状态分为以下几种:
RUNNING:运行状态,线程池一旦被创建就处于RUNNING状态,该状态的线程池会接受新任务,并处理工作队列中的任务。调用线程池的shutdown()方法,可以切换到SHUTDOWN关闭状态;调用线程池的shutdownNow()方法,可以切换到STOP停止状态。
SHUTDOWN:关闭状态,该状态线程池不会接收新任务,但会处理工作队列中的任务。当工作队列为空时,并且线程池中执行的任务也为空时,线程池会进入TIDYING()状态。
STOP:停止状态,该状态不会接收新任务,也不会处理阻塞队列中的任务,而且会中断正在运行的任务;线程池中执行的任务为空,进入TIDYING状态。
TIDYING:整理状态,所有任务已运行终止。terminated执行完毕,进入TERMINATED状态。
TERMINATED:终止状态,该线程池彻底关闭。