列举一个线程池max=6,core=3,任务队列taskQueue=5;采用饱和策略为1)
则我们看看提交任务给此线程池的执行逻辑如下:
1)首先我们提交第一个任务到线程池,此时核心线程数都还没有用,所以会启动核心线程之一来执行任务
2)接着提交第二个第三个任务到线程池,他们的执行逻辑同第一个任务是一模一样的,线程池会启动核心线程池中剩下的两个线程来执行你新提交的任务。
3)接着又有新的任务提交过来,这个时候线程池发现核心线程池中的线程已经都在工作中,所以会去看任务队列taskQueue是否满了,发现并没有,是空的,所以将这个任务放入任务队列中等待核心线程池中有空闲线程时自己来取任务执行。
4)接着又提交了4个任务到线程池,他们分别判断核心线程是否空闲,不空闲,然后判断任务队列是否已满,不满,则直接将任务放入队列;
5)接着新的任务又来,则在判断核心线程池和任务队列之后,发现任务依然没有办法处理,(max=6,core=3正在执行任务,新来一个线程,3+1<6,此时队列taskQueue已经满了,corepoolsize=3也都在干活)则会判断是否线程数达到最大,发现没有,则新启动线程来执行任务;(新的任务开始加入到执行任务中,3个corepoolsize+1个非核心线程,此时执行任务4,可理解新添加的任务是非核心线程任务在执行任务)
6)接着又来一个任务,执行流程同5,(此时有5个线程在执行任务,2个非核心线程在执行任务,3个corepoolsize在执行任务);
7)接着又来一个任务,执行流程同5,(此时有6个线程在执行任务,3个非核心线程在执行任务,3个corepoolsize在执行任务);
8)再来一个任务,发现核心线程池在忙,任务队列也满了,线程池中的全部线程也都在工作(3个corepoolsize+3个非核心线程=max(6)都在工作,如果加入新的线程则3个corepoolsize+4个非核心线程>max(6),将报拒绝异常),没有办法处理他了,所以他找到了饱和策略,因为饱和策略是默认的抛异常,所以线程池会告诉提交任务的线程,已经没有可以用的线程了。
以上就一个核心线程数是3,总线程数是6,任务队列长度为5,默认策略采用抛异常的策略的从最开始到最后线程池满负荷运作的过程
关注点1 线程池大小
线程池有两个线程数的设置,一个为核心池线程数,一个为最大线程数。
在创建了线程池后,默认情况下,线程池中并没有任何线程,等到有任务来才创建线程去执行任务,除非调用了prestartAllCoreThreads()或者prestartCoreThread()方法
当创建的线程数等于 corePoolSize 时,会加入设置的阻塞队列。当队列满时,会创建线程执行任务直到线程池中的数量等于maximumPoolSize。