目录
问题 2: 在前面30个比较耗时的任务还没执行完成的情况下,再来多少个任务会触发拒绝策略?
一、提出问题
我们首先自定义一个线程池:
new ThreadPoolExecutor(10,
30,
60,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(1000),
new NamedthreadFactory("myPool"));
拿着这个线程池,当这个线程池在正常工作的前提下,问两个问题:
- 如果这个线程池接受到了30个比较耗时的任务,这个时候线程池的 状态(或者说数据)是怎样的?
- 在前面30个比较耗时的任务还没执行完成的情况下,再来多少个任 务会触发拒绝策略?
二、解答
问题 1: 线程池在接受到30个比较耗时的任务时的状态
我们先看第一个问题,在接受到30个比较耗时的任务时,线程池的状态如下:
-
核心线程数 (
corePoolSize
):10
首先,线程池会启动10个核心线程来处理前10个任务。这些任务会立即开始执行。 -
任务队列 (
workQueue
):1000
在核心线程已经全部被占用的情况下,剩下的任务(第11个到第30个)会被放入工作队列中。这些任务会等待直到有线程空闲。 -
最大线程数 (
maximumPoolSize
):30
因为任务队列尚未达到其容量上限,所以线程池不会再创建新的线程来处理任务。也就是说,线程池中的线程数仍保持在10个。 -
线程池状态:
- 线程数:10个线程正在运行。
- 工作队列:工作队列中有20个任务在等待执行。
- 队列大小:队列中剩余可用空间为980(1000 - 20)。
因此,线程池在接受到30个耗时任务时,10个任务正在执行,20个任务在队列中等待。
问题 2: 在前面30个比较耗时的任务还没执行完成的情况下,再来多少个任务会触发拒绝策略?
在前面30个比较耗时的任务还没执行完成的情况下:
-
工作队列 (
workQueue
):- 当前工作队列中已经有20个任务在等待,还有980个空位。
-
最大线程数 (
maximumPoolSize
):30- 线程池已经启动了10个核心线程,所有核心线程都在忙碌。
- 工作队列还没有填满(容量是1000)。
因此,在此时再提交980个任务,这些任务将会被放入队列而不会触发拒绝策略。
第981个任务:当第981个任务被提交时,队列已经满了。此时,线程池将会创建新的线程来处理任务,因为还未达到最大线程数。线程池最多可以创建20个额外的线程(从10个到最大30个),这些线程会立即处理新提交的任务。
触发拒绝策略的条件:如果再提交任务使得线程池中的线程数达到了最大线程数(30个),且任务队列已满(1000个任务在等待),那么再提交第1001个任务时,就会触发拒绝策略。
总结
触发拒绝策略前:前面30个耗时任务已占据了所有核心线程和部分工作队列,队列还有980个空位。因此,接下来的980个任务可以被接受,而不会触发拒绝策略。
触发拒绝策略时:再提交的任务数使得队列满且线程数达到最大值(30个),此时再提交的任务(第1001个任务)会触发拒绝策略。