线程池一大早就来到了公司,进到了属于自己的“经理”办公室,时间才刚刚8点,虽然他不用打卡。
趁还有点时间,就给大家介绍下出席晨会的人员吧。 线程池就是Java里的大名鼎鼎的 ThreadPoolExecutor ,是经理。
六个中层管理人员分别是: int corePoolSize 、int maximumPoolSize 、long keepAliveTime 、BlockingQueue<Runnable> workQueue 、ThreadFactory threadFactory 、RejectedExecutionHandler handler 。
他们都是线程池的好基友,毕竟大家合在一起才能使公司良好运行。
8:50已到,晨会准时开始,线程池说,公司又有了新的项目,需要一批开发人员,今天约了很多面试者,我也会参与和大家一起做好面试工作。
晨会上每个中层管理分工明确,都领到了自己的工作,线程池则负责整体的协调工作。
说时迟那时快,这不,人来了。int corePoolSize
线程池问corePoolSize,现在有几个面试官在面试? corePoolSize回答到,0个。
线程池接着对threadFactory说,去请1位面试官过来,threadFactory立马请来了1位,开始给这个面试者面试。
corePoolSize赶紧在纸上记下,现有核心面试官1人,最多能有4人,面试进行中的1人。
这时又来了2位面试者,线程池又问corePoolSize同样的问题,corePoolSize如实回答。
线程池又让threadFactory请来2位面试官,正好一人面试一个。
corePoolSize也随即记录下,现有核心面试官3人,最多能有4人,面试进行中的3人。
不一会第一个面试官结束了面试,送走了面试者。 corePoolSize对面试官说,你别回去了,在这等会吧,反正待会还有人来。
corePoolSize也更新了自己的记录,现有核心面试官3人,最多能有4人,面试进行中的2人,空闲面试官1人。
不料此时又来了1位面试者,线程池看了看corePoolSize的记录,发现核心面试官虽然有1人空闲,但是还有1个名额可用。
心里想着就让空闲的面试官休息一下吧,于是又让threadFactory请来1位面试官进行面试。
corePoolSize随即又更新了自己的记录,现有核心面试官4人,最多能有4人,面试进行中的3人,空闲面试官1人。
过了一会又有一个面试官结束了面试。 corePoolSize同样让他原地休息,不用回去了。 等待接下来的人吧。
corePoolSize再次更新了自己的记录,现有核心面试官4人,最多能有4人,面试进行中的2人,空闲面试官2人。
BlockingQueue<Runnable> workQueue
空闲面试官还未休息片刻,此时又来了好几个面试者,线程池照例看了看corePoolSize的记录。 心里琢磨起来。
4位核心面试官都已就位,名额用完了。 现在只有2个空闲的,所以就只能安排2个人面试了。 把剩下的面试者交给workQueue吧。
corePoolSize赶紧更新记录,现有核心面试官4人,最多能有4人,面试进行中的4人,空闲面试官0人。
然后只见workQueue在会议室外面摆上一排椅子,总共10个,请暂时没有面试的面试者依次坐在椅子上等候。
只要一有面试者结束面试,workQueue就让等候的第一个人进去。 后面的每个人都往前坐一位。
workQueue把这个规则给坐着等候面试的人强调了几遍后,就自己找到地方偷懒去了,估计是看手机啥的。
此时又来了几个面试者,线程池还是先看corePoolSize的记录,看完后摇了摇头,直接把他们发给了workQueue。
workQueue还没有看几眼手机呢,就又被线程池给叫了去。 最终workQueue领着刚来的面试者,让他们坐到椅子上跟着一起排队等候。
新的面试者陆续不断的到来,虽然4个核心面试官都在马不停蹄的忙着,可是明显速度不够快啊。
workQueue担心照这样下去,到时我这里连坐着排队的椅子都没有了。 哎,真是怕什么来什么,这不,又来人了。
int maximumPoolSize
新来的几个面试者又被线程池发给了workQueue,待他们坐下来排队后,发现还有1位面试者没有椅子可坐了。 workQueue赶紧把这个情况报告给线程池。
线程池找来maximumPoolSize说到,4位核心面试官都在忙碌,排队等候的地儿也满了,现在轮到你了。
maximumPoolSize说,我这里一共可以出6位扩展面试官,现在一位还没出过呢,所以没有问题。
于是线程池让threadFactory去请来1位面试官,来面试这个没有椅子坐的面试者。
maximumPoolSize也赶紧记录下信息,现有扩展面试官1人,最多能有6人,面试进行中1人。
在5位面试官的努力下,椅子终于出现了空闲,后续又来的几位面试者,依然坐在椅子上排队等候。
不一会椅子又坐满了,还多出来2个面试者没地儿坐,workQueue赶紧又报告给了线程池。
线程池看了maximumPoolSize的记录,又让threadFactory去请来2位面试官,面试这2位没地儿坐的人。
maximumPoolSize随即也更新了记录,现有扩展面试官3人,最多能有6人,面试进行中3人。
long keepAliveTime
随着面试的进行,排队等待面试的人越来越少。 又过了一会,终于没有排队的了,都进入了面试中。
有一个扩展面试官结束面试了。 maximumPoolSize上前说到,你先原地休息一下吧。然后找来了keepAliveTime。
让keepAliveTime记录下这个扩展面试官开始休息的时间,并说如果5分钟后还没有新的面试者到来,就先让他回去,需要时再去叫他。
keepAliveTime随即开始了计时。 maximumPoolSize也更新了记录,现有扩展面试官3人,最多能有6人,面试进行中2人,空闲着的1人。
可能临近中午了,确实没有新的面试者到了,5分钟后,keepAliveTime让这个休息的扩展面试官回去自己的工位了。 并告知了maximumPoolSize。
maximumPoolSize也立即再次更新记录,现有扩展面试官2人,最多能有6人,面试进行中2人,空闲着的0人。
另两位扩展面试官在面试结束后,都通过相同的流程并最终回到各自的工位了。
maximumPoolSize最后更新的记录,现有扩展面试官0人,最多能有6人。
不过4位核心面试官就没有这么幸运了,他们只能原地休息等待,不能回去。
corePoolSize最后更新了自己的记录,现有核心面试官4人,最多能有4人,面试进行中的0人,空闲面试官4人。
不知不觉中午已到来,面试者都已回去,经理和中层管理都去吃饭、休息了。
RejectedExecutionHandler handler
下午2:00上班,一下子来了一屋子的面试者,线程池马上发话,我们要开足马力,尽最大限度招待面试者。
corePoolSize负责的4个核心面试官全部都在面试中。 workQueue负责的10个椅子也坐满了面试者在排队等候。
maximumPoolSize负责的6个扩展面试官也全部就位并都在面试中。 整个公司再没有一块地儿可安排多余的面试者了。
于是线程池找来了handler,让他去接待多余的面试者,其实就是适当的记录每个面试者的信息,然后直接打发他们走。
有的面试者直接就走掉了,有的面试者留下了信息说以后再联系,不管如何吧,反正多余的面试者都被handler撵走了。
handler也挺无奈的,心里想着你们干嘛都一起来呀,分散着来不行啊,我实在不想拒绝你们,可没办法,哎。
线程池心里也委屈,我只是一个经理,又不是老板,老板就给我了这么点资源啊,我太难了,转过身留下了两滴眼泪。
(END)
作者 是工作超过 10年 的码农,现在任架构师。喜欢研究技术,崇尚简单快乐。 追求以通俗易懂的语言解说技术,希望所有的读者都能看懂并记住。
>>> 热门文章集锦 <<<
毕业10年,我有话说
【面试】我是如何面试别人List相关知识的,深度有点长文
我是如何在毕业不久只用1年就升为开发组长的
爸爸又给Spring MVC生了个弟弟叫Spring WebFlux
【面试】我是如何在面试别人Spring事务时“套路”对方的
【面试】Spring事务面试考点吐血整理(建议珍藏)
【面试】我是如何在面试别人Redis相关知识时“软怼”他的
【面试】吃透了这些Redis知识点,面试官一定觉得你很NB(干货 | 建议珍藏)
【面试】如果你这样回答“什么是线程安全”,面试官都会对你刮目相看(建议珍藏)
【面试】迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)
【面试】一篇文章帮你彻底搞清楚“I/O多路复用”和“异步I/O”的前世今生(深度好文,建议珍藏)
【面试】如果把线程当作一个人来对待,所有问题都瞬间明白了
Java多线程通关———基础知识挑战
品Spring:帝国的基石
【玩转SpringBoot】配置文件yml的正确打开姿势
【玩转SpringBoot】用好条件相关注解,开启自动配置之门
【玩转SpringBoot】给自动配置来个整体大揭秘
【玩转SpringBoot】看似复杂的Environment其实很简单
【玩转SpringBoot】翻身做主人,一统web服务器
【玩转SpringBoot】让错误处理重新由web服务器接管
【玩转SpringBoot】SpringBoot应用的启动过程一览表
【玩转SpringBoot】通过事件机制参与SpringBoot应用的启动过程
【玩转SpringBoot】异步任务执行与其线程池配置
品Spring:帝国的基石
品Spring:bean定义上梁山
品Spring:实现bean定义时采用的“先进生产力”
品Spring:注解终于“成功上位”
品Spring:能工巧匠们对注解的“加持”
品Spring:SpringBoot和Spring到底有没有本质的不同?
品Spring:负责bean定义注册的两个“排头兵”
品Spring:SpringBoot轻松取胜bean定义注册的“第一阶段”
品Spring:SpringBoot发起bean定义注册的“二次攻坚战”
品Spring:注解之王@Configuration和它的一众“小弟们”
品Spring:bean工厂后处理器的调用规则
品Spring:详细解说bean后处理器
品Spring:对@PostConstruct和@PreDestroy注解的处理方法
品Spring:对@Resource注解的处理方法
品Spring:对@Autowired和@Value注解的处理方法
品Spring:真没想到,三十步才能完成一个bean实例的创建
品Spring:关于@Scheduled定时任务的思考与探索,结果尴尬了