线程池源码分析之ThreadPoolExecutor
Posted 老吕架构
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程池源码分析之ThreadPoolExecutor相关的知识,希望对你有一定的参考价值。
前言
今天老吕给大家来分享下ThreadPoolExecutor 线程池的实现逻辑,大家伙认真看,一般人我不告诉他的。
线程池相关类图
JDK中线程池相关的类结构关系图
获取不同特性的线程池
在Executors中可以获取到如下类型的线程池:
//下面这几种线程池的实现基础都是ThreadPoolExecutor 线程池实现类
static ExecutorService executorService1 = Executors.newFixedThreadPool(10);
static ExecutorService executorService2 = Executors.newCachedThreadPool();
static ExecutorService executorService3 = Executors.newSingleThreadExecutor();
static ExecutorService executorService4 = Executors.newScheduledThreadPool(10);
static ExecutorService executorService5 = Executors.newSingleThreadScheduledExecutor();
//它的实现比较特殊用的ForkJoinPool 线程池实现类
static ExecutorService executorService6 = Executors.newWorkStealingPool();
ThreadPoolExecutor的实现逻辑
上面6种类型的线程池,大部分是以ThreadPoolExecutor为基础来实现的,我们今天只分析 ThreadPoolExecutor的实现逻辑。
首先看下著名的7大参数
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
这是我总结的7大参数的含义,很简单是吧
下面看下线程池线程数量扩张与任务队列的关系,仔细体会
在源码中Worker本质上就是一个Thread,只有第一个任务(firstTask)是通过构造函数传进去的,之后执行的任务都是通过任务队列获取,从而也可以看出任务的本质是实现了Runnable接口的消息而已。
最后总结下这个线程池的实现逻辑
1、一个任务过来后,除了 新增一个线程时会将任务直接送到新线程里面
2、其它情况下所有的任务都是先放入任务队列
3、线程池中的所有线程一视同仁都是从任务队列中获取任务
4、假如你的最大线程个数为100,任务队列容量为很小,比如:容量为10,在并发较高场景下就会出现 池中线程 空闲线程很多,但是客户端收到 拒绝执行的奇怪现象。如果你理解了前3点,这个现象的原因你也就知道了。
5、谢谢大家,今天就到这里,有疑问加作者微信,进群探讨。
以上是关于线程池源码分析之ThreadPoolExecutor的主要内容,如果未能解决你的问题,请参考以下文章
ElasticSearch 线程池类型分析之SizeBlockingQueue