看到一个魔改线程池,面试素材加一! (5)

com.github.phantomthief.pool.KeyAffinityExecutorUtils#executor(java.lang.String, int)

在这里可以看到我们一直提到的“只有一个线程的线程池”,队列的长度也可以指定:

看到一个魔改线程池,面试素材加一!

该方法返回的是一个 Supplier 接口,等下就要用到。

接下来,我们要找到 “3” 这个数字是体现在哪儿的呢?

就藏在构造函数的 build 方法里面,该方法最终会调用到这个方法来:

com.github.phantomthief.pool.impl.KeyAffinityImpl#KeyAffinityImpl

你到时候在这个地方打个断点,然后 Debug 看一眼,就非常明确了:

看到一个魔改线程池,面试素材加一!

关于框起来的这部分的几个关键参数,我解释一下:

看到一个魔改线程池,面试素材加一!

首先是 count 参数,就是我们定义的 3。那么 range(0,3),就是 0,1,2。

然后是 supplier,这玩意就是前面我们说的 executor 方法返回的 supplier 接口,可以看到里面封装的就是个线程池。

接着是里面有一个非常关键的操作 :map(ValueRef::new)。

这个操作里面的 ValueRef 对象,很关键:

com.github.phantomthief.pool.impl.KeyAffinityImpl.ValueRef

看到一个魔改线程池,面试素材加一!

关键的地方就是这个对象里面的 concurrency 变量。

还记得最前面说的“挑选最闲置的执行器(线程池)”这句话吗?

怎么判断是否闲置?

靠的就是 concurrency 变量。

其对应的代码在这:

com.github.phantomthief.pool.impl.KeyAffinityImpl#select

看到一个魔改线程池,面试素材加一!

能走到断点的地方,说明当前这个 key 是之前没有被映射过的,所以需要为其指定一个线程池。

而指定这个线程池的操作,就是循环这个 all 集合,集合里面装的就是 ValueRef 对象:

看到一个魔改线程池,面试素材加一!

所以,comparingInt(ValueRef::concurrency) 方法就是在选当前所有的线程池,并发度最小的一个。

如果这个线程池从来没有用过或者目前没有任务在使用,那么并发度必然是 0 ,所有会被选出来。

如果所有线程池正在被使用,就会选 concurrency 这个值最低的线程池。

我这里只是给大家说一个大概的思路,如果要深入了解的话,自己去翻源码去。

如果你非常了解 lambdas 的用法的话,你会觉得写的真的很优雅,看起来很舒服。

如果你不了解 lambdas 的话...

那你还不赶紧去学?

另外我还发现了两个熟悉的东西。

朋友们,请看这是什么:

看到一个魔改线程池,面试素材加一!

这难道不就是线程池参数的动态调整吗?

第二个是这样的:

看到一个魔改线程池,面试素材加一!

RabbitMQ 里面的动态调整我也写过啊,也是强调过这三处地方:

增加 {@link #setCapacity(int)} 和 {@link #getCapacity()}

{@link #capacity} 判断边界从 == 改为 >=

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwfzjd.html