本文章对ThreadPoolExecutor线程池的底层源码进行分析,线程池如何起到了线程复用、又是如何进行维护我们的线程任务的呢?我们直接进入正题:
首先我们看一下ThreadPoolExecutor类的源码
1 public ThreadPoolExecutor(int corePoolSize,
2 int maximumPoolSize,
3 long keepAliveTime,
4 TimeUnit unit,
5 BlockingQueue<Runnable> workQueue,
6 ThreadFactory threadFactory,
7 RejectedExecutionHandler handler) {
//拒绝策略
8 if (corePoolSize < 0 ||
9 maximumPoolSize <= 0 ||
10 maximumPoolSize < corePoolSize ||
11 keepAliveTime < 0)
12 throw new IllegalArgumentException();
13 if (workQueue == null || threadFactory == null || handler == null)
14 throw new NullPointerException();
15 this.acc = System.getSecurityManager() == null ?
16 null :
17 AccessController.getContext();
18 //核心线程
19 this.corePoolSize = corePoolSize;
20 //最大线程数
21 this.maximumPoolSize = maximumPoolSize;
22 //阻塞队列,即今天主题
23 this.workQueue = workQueue;
24 //超时时间
25 this.keepAliveTime = unit.toNanos(keepAliveTime);
26 this.threadFactory = threadFactory;
27 //拒绝策略
28 this.handler = handler;
29 }
这是我们线程池实例化的时候的参数,其实最大的实用性来说,就是核心线程与最大线程数的设定,这个完全靠个人经验,并没有一个真正意义上的公式可以适用所有的业务场景。
我们的线程池初始化好后,我们自己会调用excute方法来让线程池运行我们的线程任务,那我们就先来看看这个方法的实现:
1 public void execute(Runnable command) {
2 if (command == null)
3 throw new NullPointerException();
4 /*
5 * 第一步:工作线程是否小于核心线程数量,如果是添加work中,worker其实也是一个线程,只不过它内部操作的是我们的上传的任务
6 * 第二步:如果大于核心线程数量,添加到worker队列中,每一个不同的队列offer的实现方法也是不一样的,今天我们主要探讨这个
7 * 第三步:阻塞队列被塞满了,需要创建新的非核心线程数量worker线程去处理我们的任务,创建worker线程失败了会触发拒绝策略,默认抛异常
8 */
9 int c = ctl.get();
10 if (workerCountOf(c) < corePoolSize) {
11 if (addWorker(command, true))
12 return;
13 c = ctl.get();
14 }
15 if (isRunning(c) && workQueue.offer(command)) {
16 int recheck = ctl.get();
17 if (! isRunning(recheck) && remove(command))
18 reject(command);
19 else if (workerCountOf(recheck) == 0)
20 addWorker(null, false);
21 }
22 else if (!addWorker(command, false))
23 reject(command);
24 }
25
我们看到当任务调用的时候,会执行addworker,那么worker是个什么东西呢?我们来看看它的构造实例:我们看一下worker类,就发现其实worker也是一个线程
1 private final class Worker
2 extends AbstractQueuedSynchronizer
3 implements Runnable
4 {
5
6 ......
7
8 Worker(Runnable firstTask) {
9 setState(-1); // inhibit interrupts until runWorker
10 this.firstTask = firstTask;
11 this.thread = getThreadFactory().newThread(this);
12 }
13
14 /** 覆盖执行run方法
15 */
16 public void run() {
17 runWorker(this);
18 }
19 ......
20
21 }
这次我们来看一下addworker是怎么操作的:
1 private boolean addWorker(Runnable firstTask, boolean core) {
2 retry:
3 for (;;) {
4 int c = ctl.get();
5 int rs = runStateOf(c);
6
7 // Check if queue empty only if necessary.
8 if (rs >= SHUTDOWN &&
9 ! (rs == SHUTDOWN &&
10 firstTask == null &&
11 ! workQueue.isEmpty()))
12 return false;
13
14 for (;;) {
15 int wc = workerCountOf(c);
16 if (wc >= CAPACITY ||
17 //不允许创建大于最大核心线程数的任务
18 wc >= (core ? corePoolSize : maximumPoolSize))
19 return false<