(给ImportNew加星标,提高Java技能)
作者:孤独烟
https://mp.weixin.qq.com/s/sRfLCpn6VRF6760DFDxyDQ
引言
面试官:"假设我们有一个线程池,核心线程数为10,最大线程数也为20,任务队列为100。现在来了100个任务,线程池里现在有几个线程运行?"
其实这道题正确的答案是"不一定!"因为并没指明是哪一种线程池机制,带着我们的疑问继续往下看!ps:不要纠结这题是不是咬文嚼字,现在人多如米,题目就是这样坑~正文
先进队列,到最大值,再起线程
这种情况是大家最容易想到的情况,因为JDK中的线程池,也就是ThreadPoolExecutor就是这种机制的!OK,我们先来看一下ThreadPoolExecutor的execute方法,如下图所示
![]()
看到三个红框了吧(其实源码里有解释),对应的三步分别是
如图所示,默认的机制为线程池里的核心线程数不够了,后面进来的任务会先丢队列,当队列满了,才起新线程。
因此,按照这套机制!粉丝豪的回答是正确的,当有100个任务添加进来时,剩下先起10个核心线程,剩下90个任务都丢进队列里,因此线程池里只有10个线程在执行!先起线程,到最大值,再进队列
不知道大家有没听过在dubbo中,有一种线程池叫EagerThreadPoolExecutor线程池。
它调的还是父类的execute方法,也还是ThreadPoolExecutor中的execute方法!
但是,它的队列!是一种自定义队列,叫TaskQueue,它的offer方法如下![]()
这个offer方法的最核心的是红框中那步,当前线程数小于最大线程数时,则直接返回false。ThreadPoolExecutor中的execute方法中的第二步的条件中,如果workQueue.offer返回为fasle,则直接进入第三步,创建新任务!如下图所示
EagerThreadPoolExecutor线程池通过自定义队列的这么一种形式,改写了线程池的机制。这种线程池的机制是核心线程数不够了,先起线程,当线程达到最大值后,后面的任务就丢进队列!因此,如果按照这么一套机制,粉丝豪的答案就不正确了。当100个任务添加进来时,直接会起20个线程,剩下80个任务都丢进队列!发散题
这是一道真实的发散题,其实问法也是差不多的。如果上面的内容能看懂,这道题也能答的上来!
总结
看完本文有收获?请转发分享给更多人
关注「ImportNew」,提升Java技能
![]()
好文章,我在看❤️