多线程笔记(三)线程池 ThreadPoolExecutor

1. ctl:将 workerCount(工作线程的数量)和线程池的状态放在一个 int 中保存

    在 ctolOf 方法中实现

private static int ctlOf(int rs, int wc) { return rs | wc; }

    作用:并不是节省空间,而是为了保持线程池状态和运行状态的统一,放在一个变量里,可以保证这两部分同时修改
2. 五种状态,需要三个 bit 来表示,所以高 3 位表示状态,剩下的 29 位表示工作线程的数量,因此线程池中工作线程的最大数量为 $2^29−1$

    也就是 ThreadPoolExecutor.CAPACITY(高三位为 0,低 29 位为 1)

private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

    计算工作线程的数量:workerCountOf 方法。和 CAPACITY 做 & 运算,由于 CAPACITY 的低 29 位都为 1,所以可以取出工作线程的数量

private static int workerCountOf(int c)  { return c & CAPACITY; }

    获取线程池状态:要取 ctl 的高三位的值,因此先把 CAPACITY 取反,然后和 ctl 做 & 运算

private static int runStateOf(int c)     { return c & ~CAPACITY; }

3. execute 方法

 1 public void execute(Runnable command) {
 2     if (command == null)
 3         throw new NullPointerException();
 4 
 5     // 获取当前线程池的状态
 6     int c = ctl.get();
 7     // 当工作线程数 < 核心线程池容量时,添加工作线程去执行任务
 8     if (workerCountOf(c) < corePoolSize) {
 9         if (addWorker(command, true))
10             return;
11         // 重新获取状态
12         c = ctl.get();
13     }
14     // 达到核心池上限,尝试加入缓存队列
15     if (isRunning(c) && workQueue.offer(command)) {
16         int recheck = ctl.get();
17         // 再次检查线程池状态
18         if (! isRunning(recheck) && remove(command))// 线程池没有在运行,将任务移出队列,并执行拒绝策略
19             reject(command);
20         else if (workerCountOf(recheck) == 0)// 线程池中没有线程,需要创建新的线程,传入 null 是因为创建的线程去队列里取任务,不需要指定执行的任务
21             addWorker(null, false);
22     }
23     else if (!addWorker(command, false)) // 缓存队列已满,尝试创建新的线程
24         reject(command);
25 }

4. addWorker 方法

 

 1 private boolean addWorker(Runnable firstTask, boolean core) {
 2     retry:
 3     for (;;) { // loop1
 4         int c = ctl.get();
 5         int rs = runStateOf(c);
 6 
 7         // Check if queue empty only if necessary.
 8         // 此处 if 判断为 False 只有两种情况:rs 为 running(也就是 < shutdown),当然可以继续添加线程;还有就是虽然线程池已经 shutdown,但是不会添加新的任务(firstTask == null),同时队列里还有任务,也就是(rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty()),其他情况都是 True,需要停止添加线程,返回 false
 9         if (rs >= SHUTDOWN &&
10             ! (rs == SHUTDOWN &&
11                firstTask == null &&
12                ! workQueue.isEmpty()))
13             return false;
14 
15         for (;;) {
16             int wc = workerCountOf(c);
17             if (wc >= CAPACITY ||
18                 wc >= (core ? corePoolSize : maximumPoolSize))
19                 return false;
20             // CAS 使 workCount 加 1,成功则退出 loop1,继续下面的代码
21             if (compareAndIncrementWorkerCount(c))
22                 break retry;
23             c = ctl.get();  // Re-read ctl
24             // CAS 操作失败,重新检查状态,如果线程池状态改变,进行外部循环(loop1)
25             if (runStateOf(c) != rs)
26                 continue retry;
27             // else CAS failed due to workerCount change; retry inner loop
28             // 线程池状态不变的话,继续内部循环,尝试使 workCount 加 1
29         }
30     }
31 
32     boolean workerStarted = false;
33     boolean workerAdded = false;
34     Worker w = null;
35     try {
36         // 创建新线程
37         w = new Worker(firstTask);
38         final Thread t = w.thread;
39         if (t != null) {
40             final ReentrantLock mainLock = this.mainLock;
41             mainLock.lock();
42             try {
43                 // Recheck while holding lock.
44                 // Back out on ThreadFactory failure or if
45                 // shut down before lock acquired.
46                 int rs = runStateOf(ctl.get());
47                 
48                 // 检查线程池状态
49                 if (rs < SHUTDOWN ||
50                     (rs == SHUTDOWN && firstTask == null)) {
51                     if (t.isAlive()) // precheck that t is startable
52                         throw new IllegalThreadStateException();
53                     workers.add(w);
54                     int s = workers.size();
55                     if (s > largestPoolSize)
56                         largestPoolSize = s;
57                     workerAdded = true;
58                 }
59             } finally {
60                 mainLock.unlock();
61             }
62             if (workerAdded) {
63                 // 启动线程
64                 t.start();
65                 workerStarted = true;
66             }
67         }
68     } finally {
69         if (! workerStarted)
70             addWorkerFailed(w);
71     }
72     return workerStarted;
73 }

 

posted @ 2019-08-18 20:28  Ainsliaea  阅读(266)  评论(0编辑  收藏  举报