线程池的工作流程主要包括任务提交、线程分配、任务执行和线程回收等环节,以下是对其详细的描述:
-
任务提交
- 当有任务需要执行时,用户通过线程池提供的提交方法,如
execute()
或submit()
方法,将任务(通常是实现了Runnable
接口或Callable
接口的对象)提交给线程池。
- 当有任务需要执行时,用户通过线程池提供的提交方法,如
-
线程分配
- 判断核心线程是否已满:线程池首先会检查当前正在运行的线程数量是否小于核心线程数
corePoolSize
。如果是,线程池会创建一个新的线程来执行提交的任务。 - 任务入队:如果当前线程数量已经达到核心线程数,那么线程池会尝试将任务放入任务队列
workQueue
中。如果任务队列是有界队列且尚未满,任务会被成功放入队列中等待执行。 - 判断最大线程数:如果任务队列已满,线程池会检查当前线程数量是否小于最大线程数
maximumPoolSize
。如果是,线程池会创建新的线程来执行任务,即使核心线程都在忙碌状态。
- 判断核心线程是否已满:线程池首先会检查当前正在运行的线程数量是否小于核心线程数
-
任务执行
- 当有空闲线程时,它会从任务队列中获取任务。线程池中的线程在执行任务时,会调用任务的
run()
方法(如果是Runnable
任务)或call()
方法(如果是Callable
任务)来执行具体的业务逻辑。 - 如果任务执行过程中出现异常,默认情况下线程池会将异常抛出。不过,可以通过自定义的方式来处理这些异常,比如记录日志等。
- 当有空闲线程时,它会从任务队列中获取任务。线程池中的线程在执行任务时,会调用任务的
-
线程回收
- 判断是否为多余线程:当任务执行完成后,线程不会立即销毁,而是会进入空闲状态并等待新的任务。如果当前线程池中的线程数量超过了核心线程数,并且这些多余的线程在一定时间(
keepAliveTime
)内没有接收到新的任务,那么这些线程会被销毁,以释放资源。 - 保持核心线程:核心线程默认情况下会一直存在于线程池中,即使它们处于空闲状态,除非设置了
allowCoreThreadTimeOut(true)
,这样核心线程在空闲时间超过keepAliveTime
后也会被回收。
- 判断是否为多余线程:当任务执行完成后,线程不会立即销毁,而是会进入空闲状态并等待新的任务。如果当前线程池中的线程数量超过了核心线程数,并且这些多余的线程在一定时间(
-
拒绝策略处理
- 如果线程池中的线程数量已经达到最大线程数
maximumPoolSize
,并且任务队列也已满,此时再提交新的任务,线程池会根据设置的拒绝策略handler
来处理这些任务。如采用AbortPolicy
策略会直接抛出异常,CallerRunsPolicy
策略会让提交任务的线程来执行任务等。
- 如果线程池中的线程数量已经达到最大线程数