线程池是怎么回收空闲线程的?如果你认为有定时任务,那你就错了!

全文共计1820字17图,预计阅读时间12分钟

大家好,我是tin,这是我的第4篇原创文章
v2-3e37da86c900fe14e1cf7331afaf764f_1440w.jpg

一、来唠嗑唠嗑题外话

配图和本文内容无关,之所以留此配图是因为最近自己作为万年windows系统用户终于尝试买入了人生第一台mac,也就是今年刚出来,大家都比较关心、讨论也满天飞的mac M1!此文作为使用mac输出的第一篇技术文章,谨此纪念。

感觉怎么样呢?作为一个完全mac新用户,主要的体会是这样的:

  1. 续航真真长!自己亲测,17-18小时毫无压力。

  2. 很不习惯。包括了macOS、快捷键、触摸板、文件管理,到目前为止我还没弄明白control、option、command这三个键的区别。

  3. 整机质感很好。最想说的就是屏幕,很细、很腻、很柔,非常有一种舒服感、质感,大体有些「遇见即要护你终生」的感觉。

至于网上一直讨论的兼容性问题,目前还没遇到,因为我本机用的最多的是浏览器、微信、IDEA,这些都能正常运行。

好了,回归正题。

二、究竟谁负责回收线程池空闲线程?

这个问题的来源也是比较巧,曾经跟同事聊天,说怎么去考量候选人简历上的“精通Java线程池”,考虑出发点一是不能网上出现过的,因为可以背答案,二是要能体现候选人真的懂线程池,起码源码看过(非熟悉使用Java线程池)。

一次面试的时候,同事突然想到的这个问题。于是今天我就把这个问题作为本文分析线程池的出发点了。

首先,这个问题常见的答案有:

① 线程池回收的 ---等于没答

② 会单独有一个定时任务回收空闲线程 ---完全错误

正确答案是这样的:

超过corePoolSize的空闲线程由线程池回收,线程池Worker启动跑第一个任务之后就一直循环遍历线程池任务队列,超过指定超时时间获取不到任务就remove Worker,最后由垃圾回收器回收。

这里面有两个概念想重新说一下,一个是Worker,另一个是任务队列。

Worker是线程池ThreadPoolExecutor的一个内部类,其有一个成员变量thread(线程),所以我们可以把一个Worker假以理解为一个线程。

任务队列是BlockingQueue,都说精通线程池了,如果熟悉这个队列的话,能不熟悉它的几个方法吗?线程池正是利用poll方法的超时时间来决定要不要回收空闲线程的。

boolean poll(E e, long timeout, TimeUnit unit)

三、源码一窥究竟

讲完答案,一起看看怎么举证它,先把测试用例写起来:

iShot2021-01-03 10.29.12.png

定义了核心线程数为1,最大线程数为2,队列长度为2的线程池,程序运行时一次性给线程池安排4个任务,重复两次,下面是运行的结果截图:


image.png

从现象看,我们的问题复现出来了!已经复现那就好办了,可以打断点进去一看究竟了(为了便于分析理解,我就没有把debug截图出来,都是关键源码截图)!

我们再回顾下线程池的类图,要不然我们还不知道在哪里看,在哪里下手打断点是不是?


iShot2021-01-03 11.28.07.png

ThreadPoolExecutor至关重要,它就是我们所说的线程池了。Executors给了很多生成默认线程池的方法,但一般不建议用Executors的默认线程池,具体原因不在本文讨论范围之内,有兴趣可以先自行了解。

已经找到ThreadPoolExecutor关键类, 再上一个线程池运行任务的基本流程图


iShot2021-01-03 20.18.23.png

有了这图是不是就很清晰了?重点在「线程执行任务」里面,接下来我们开始看源码。

从ThreadPoolExecutor的excute方法看起,为什么从这里看起?因为我们的任务放到线程池后,是从调用execute执行开始的。


image.png

execute主体代码量很少,我特地圈出了addWorker,里面最最重要的就是初始化Worker同时启动thread。


image.png

上图是Worker作为内部类最关键的代码,非常有意思的是Worker本身也是一个Runnable,它把自己放到自己的成员变量thread里面来执行了!thread顾名思义就是线程了。

这样就明了了,Worker实现了Runnable接口,我们直接看它的run方法,看截图的③处标记,抽离出来一个runWorker方法,我们直接看runWorker方法,看下图:


iShot2021-01-03 20.39.22.png

①处是一个while循环,getTask方法就是从线程池队列取任务,里面就是上面我说到的调用BlockingQueue的poll方法,超时时间即是我们配置线程池事的keepAliveTime。

②处就是我们本问题真正答案之处了呀!发现没,一旦跳出while循环,即进入到processWorkExit方法,这就是回收Worker,答案终于浮出水面,看下面截图:


image.png

细心的同学可能发现了,这个回收岂不是把核心线程也会回收?

非也,这个问题的答案在getTask方法里面,来,我们再看一下getTask方法:


iShot2021-01-03 21.04.09.png

①处表示是否允许核心线程超时,或者线程数是否大于核心线程数。(这里说一下一个非常细的点:线程池中如果线程数低于核心线程数,就一定不会回收线程了吗?答案显然不是,allowCoreThreadTimeOut参数不就可以实现回收了么!)

②处就是从任务队列取任务了,带了timeOut参数的poll方法超时未能从任务队列获取任务即返回null,从而实现最终的线程回收。

四、结束求关注

我是tin,一个在努力让自己早日变成大神的普通攻城狮。自己阅历有限、学识浅薄,如有发现文章不妥之处,非常欢迎加我提出,我一定细心推敲加以修改。


20190911181805AMQR5B8FDFDAXGLA.gif

看到这里请给我点个赞再走吧,坚持原创不容易,不要白嫖,你的正反馈是我坚持输出的最强大动力,谢谢!

最后别忘了关注我哦

总结、提升

做一个快乐的攻城狮

构筑属于自己的一方天地

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容