理解:
线程池的创建参数,就像⼀个银⾏。
- corePoolSize 就像银⾏的“当值窗⼝“,⽐如今天有2位柜员在受理客户请求(任务)。 如果超过2个客户,那么新的客户就会在等候区(等待队列 workQueue )等待。
- 当等候区也满了,这个时候就要开启“加班窗⼝”,让其它3位柜员来加班,此时达到最⼤窗⼝ maximumPoolSize ,为5个。
- 如果开启了所有窗⼝,等候区依然满员,此时就应该启动”拒绝策略“ handler ,告诉不断涌⼊的客户,叫他们不要进⼊,已经爆满了。
- 由于不再涌⼊新客户,办完事的客户增多,窗⼝开始空闲,这个时候就通过 3个”加班窗⼝“取消,恢复到2个”当值窗⼝“。
案例图:
原理图:
上⾯银⾏的例⼦,实际上就是线程池的⼯作原理。
流程图:
流程:
1. 在创建了线程池后,开始等待请求。
2. 当调⽤execute()⽅法添加⼀个请求任务时,线程池会做出如下判断:
- 2.1 如果正在运⾏的线程数量⼩于 corePoolSize ,那么⻢上创建核⼼线程运⾏执⾏这个任务;
- 2.2 如果正在运⾏的线程数量⼤于或等于 corePoolSize ,那么将这个任务放⼊队列;
- 2.3 如果这个时候等待队列已满,且正在运⾏的线程数量⼩于 maximumPoolSize ,那么还是要创 建⾮核⼼线程⽴刻运⾏这个任务;
- 2.4 如果这个时候等待队列已满,且正在运⾏的线程数量⼤于或等于 maximumPoolSize ,那么线 程池会启动饱和拒绝策略来执⾏。
3. 当⼀个线程完成任务时,它会从等待队列中取出下⼀个任务来执⾏。
4. 当⼀个线程⽆事可做超过⼀定的时间( keepAliveTime )后,线程会判断:
- 如果当前运⾏的线程数⼤于corePoolSize ,那么这个⾮核⼼线程就被停掉。
- 当线程池的所有任 务完成后,它最终会收缩到corePoolSize的⼤⼩。
《Java 开发⼿册》是阿⾥巴巴集团技术团队: