参考答案
1. 线程池的工作流程
线程池的具体实现过程较为复杂,下面附线程池的工作精简图参考,基本能覆盖到线程池的整个工作流程。
2. 整个实现过程,主要有以下几个部分:
- 当一个任务通过submit或者execute方法提交到线程池的时候,如果当前池中线程数(包括闲置线程)小于coolPoolSize,则创建一个线程执行该任务。
- 如果当前线程池中线程数已经达到coolPoolSize,则将任务放入等待队列。
- 如果任务不能入队,说明等待队列已满,若当前池中线程数小于maximumPoolSize,则创建一个临时线程(非核心线程)执行该任务。
- 如果当前池中线程数已经等于maximumPoolSize,此时无法执行该任务,根据拒绝执行策略处理。
注意:
- 当池中线程数大于coolPoolSize,超过keepAliveTime时间的闲置线程会被回收掉,回收的是非核心线程,核心线程一般是不会回收的。
- 如果设置allowCoreThreadTimeOut(true),则核心线程在闲置keepAliveTime时间后也会被回收。
- 任务队列是一个阻塞队列,线程执行完任务后会去队列取任务来执行,如果队列为空,线程就会阻塞,直到取到任务。
我们假定有这个场景:
corePoolSize:1 mamximumPoolSize:3 keepAliveTime:60s workQueue:ArrayBlockingQueue,有界阻塞队列,队列大小是4 handler:默认的策略,抛出来一个ThreadPoolRejectException
以下是新任务来时的场景:以poolSize=0 表示线程数量:
1.来了一个任务,poolSize<corePoolSize 新建一个线程 2.又来了一个任务,poolSize>=corePoolSize ,队列未满,将任务丢入队列等待执行 3.继续添加任务,如果队列满了,而 poolSize < maximum,此时将会新建线程 4.如果继续添加任务,队列满,线程数量达到maximum,则会让handler 去处理。默认抛出异常 5.如果现在线程数量是3,但是都处于空闲状态,空闲超过60s 之后,其中2个线程就会被回收,保留一个(coolPoolSize=1)
所以,当任务来临时的处理顺序是这样的:
首先创建 corePoolSize 线程 然后丢到队列等待 队列满,新建maximum线程 继续满,handler 处理
以上,是Java面试题【线程池的工作流程是怎样的】的参考答案。
输出,是最好的学习方法。
欢迎在评论区留下你的问题、笔记或知识点补充~
—end—