線程池源碼解讀

參考文檔: https://www.jianshu.com/p/a977ab6704d7

 

源碼位置: java.util.concurrent.ThreadPoolExecutor#execute

jdk 版本: 1.8

  3      *
  4      *   RUNNING:  Accept new tasks and process queued tasks
  5      *   SHUTDOWN: Don't accept new tasks, but process queued tasks
  6      *   STOP:     Don't accept new tasks, don't process queued tasks,
  7      *             and interrupt in-progress tasks
  8      *   TIDYING:  All tasks have terminated, workerCount is zero,
  9      *             the thread transitioning to state TIDYING
 10      *             will run the terminated() hook method
 11      *   TERMINATED: terminated() has completed
 12      *
 13      * The numerical order among these values matters, to allow
 14      * ordered comparisons. The runState monotonically increases over
 15      * time, but need not hit each state. The transitions are:
 16      *
 17      * RUNNING -> SHUTDOWN
 18      *    On invocation of shutdown(), perhaps implicitly in finalize()
 19      * (RUNNING or SHUTDOWN) -> STOP
 20      *    On invocation of shutdownNow()
 21      * SHUTDOWN -> TIDYING
 22      *    When both queue and pool are empty
 23      * STOP -> TIDYING
 24      *    When pool is empty
 25      * TIDYING -> TERMINATED
 26      *    When the terminated() hook method has completed terminated()
 27      */
 28     
 29     // 前三位表示運行狀態,後面存儲當前運行 workerCount
 30     private static final int COUNT_BITS = Integer.SIZE - 3; // 32 - 3
 31     
 32     // 最大容量
 33     private static final int CAPACITY   = (1 << COUNT_BITS) - 1; // 00011111111111111111111111111111
 34     
 35     /**
 36      * Maximum pool size. Note that the actual maximum is internally
 37      * bounded by CAPACITY. 實際線程池大小還是由 CAPACITY 決定
 38      */
 39     private volatile int maximumPoolSize;
 40     
 41     // 線程池的幾個狀態 官方註釋在最上方
 42     // 接受新的任務
 43     private static final int RUNNING    = -1 << COUNT_BITS; // 11100000000000000000000000000000
 44     
 45     // 不接受新的任務,但是已在隊列中的任務,還會繼續處理
 46     private static final int SHUTDOWN   =  0 << COUNT_BITS; // 00000000000000000000000000000000
 47     
 48     // 不接受,不處理新的任務,且中斷正在進行中的任務
 49     private static final int STOP       =  1 << COUNT_BITS; // 00100000000000000000000000000000
 50     
 51     // 所有任務已停止,workerCount 清零,注意 workerCount 是由 workerCountOf(int c) 計算得出的
 52     private static final int TIDYING    =  2 << COUNT_BITS; // 01000000000000000000000000000000
 53     
 54     // 所有任務已完成
 55     private static final int TERMINATED =  3 << COUNT_BITS; // 01100000000000000000000000000000
 56     
 57     // 線程池運行狀態和已工作的 workerCount 初始化爲 RUNNING 和 0
 58     private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
 59     
 60     // 計算當前 state
 61     // ~CAPACITY 爲 11100000000000000000000000000000 & c(假如前三位爲 000)說明線程池已經 SHUTDOWN
 62     private static int runStateOf(int c)     { return c & ~CAPACITY; }
 63     
 64     // 同時拿到 state workerCount
 65     private static int ctlOf(int rs, int wc) { return rs | wc; }
 66     
 67     // & 可以計算出當前工作的 workerCount
 68     private static int workerCountOf(int c)  { return c & CAPACITY; }
 69     
 70     // 線程入列
 71     public void execute(Runnable command) {
 72             if (command == null)
 73                 throw new NullPointerException();
 74        
 75                // 獲取線程池 state 和 workerCount
 76                // 判斷是否滿足加入核心線程
 77             int c = ctl.get();
 78             if (workerCountOf(c) < corePoolSize) {
 79                 // 以核心線程的方式加入隊列
 80                 if (addWorker(command, true))
 81                     return;
 82                 // 添加失敗 獲取最新的線程池 state 和 workerCount
 83                 c = ctl.get();
 84             }
 85             // 在運行且成功加入隊列
 86             if (isRunning(c) && workQueue.offer(command)) {
 87                 int recheck = ctl.get();
 88                 //防止線程池狀態發生了變化, 再檢查一次,不是運行狀態就拒絕任務
 89                 if (!isRunning(recheck) && remove(command))
 90                     reject(command);
 91                 else if (workerCountOf(recheck) == 0)
 92                     // 加入一個 null
 93                     addWorker(null, false);
 94             }
 95             // 加入失敗就拒絕任務
 96             else if (!addWorker(command, false))
 97                 reject(command);
 98         }
 99   
100 // 實際的操作 101 private boolean addWorker(Runnable firstTask, boolean core) { 102 retry: 103 for (;;) { 104 // 獲得當前 state 和 workerCount 105 int c = ctl.get(); 106 int rs = runStateOf(c); 107 108 // 大於等於 SHUTDOWN 即 SHUTDOWN, STOP TIDYING TERMINATED (SHUTDOWN需要排除 隊列中不爲空的情況, 這個狀態不接受新任務, 需要把當前任務處理完) 109 // Check if queue empty only if necessary. 110 if (rs >= SHUTDOWN && 111 ! (rs == SHUTDOWN && 112 firstTask == null && 113 ! workQueue.isEmpty())) 114 return false; 115 116 for (;;) { 117 // 計算 workerCount 118 int wc = workerCountOf(c); 119 if (wc >= CAPACITY || 120 wc >= (core ? corePoolSize : maximumPoolSize)) 121 return false; 122 // 成功了就退出 123 if (compareAndIncrementWorkerCount(c)) 124 break retry; 125 c = ctl.get(); // Re-read ctl 126 if (runStateOf(c) != rs) 127 // 狀態發了變化, 進行重試 128 continue retry; 129 // else CAS failed due to workerCount change; retry inner loop 130 } 131 }
// 上面的邏輯, 主要是對線程(worker)數量進行加一操作(原子性),下面
132 133 boolean workerStarted = false; 134 boolean workerAdded = false; 135 Worker w = null; 136 try { 137 // 統一線程的名字 138 // 設置 daemon 和 priority 139 w = new Worker(firstTask); 140 final Thread t = w.thread; 141 if (t != null) {
// 加入可重入鎖
142 final ReentrantLock mainLock = this.mainLock; 143 mainLock.lock(); 144 try { 145 // Recheck while holding lock. 146 // Back out on ThreadFactory failure or if 147 // shut down before lock acquired. 148 int rs = runStateOf(ctl.get()); 149 150 // 異常檢查 (rs== SHUTDOWN, firstTask必然是null, 原因是這個狀態拒絕接受新任務, 這麼寫更嚴謹一些 ) 151 if (rs < SHUTDOWN || 152 (rs == SHUTDOWN && firstTask == null)) {
                    // 檢查線程狀態, 165行才啓動線程, 按道理線程線程狀態不可能是alive 狀態
153 if (t.isAlive()) // precheck that t is startable 154 throw new IllegalThreadStateException(); 155 workers.add(w); 156 int s = workers.size(); 157 if (s > largestPoolSize) 158 largestPoolSize = s; 159 workerAdded = true; 160 } 161 } finally { 162 mainLock.unlock(); 163 } 164 // 添加成功 啓動線程 165 if (workerAdded) { 166 t.start(); 167 workerStarted = true; 168 } 169 } 170 } finally { 171 // 加入失敗 172 if (! workerStarted) 173 addWorkerFailed(w); 174 } 175 return workerStarted; 176 } 177

178 // 加入失敗 做一些掃尾清理(回滾操作)
     // 1. 工作線程數量減1 2. 工作線程隊列移除當前worker 179 private void addWorkerFailed(Worker w) { 180 final ReentrantLock mainLock = this.mainLock; 181 mainLock.lock(); 182 try { 183 if (w != null) 184 workers.remove(w); 185 // workerCount-1 186 decrementWorkerCount(); 187 // 嘗試更新狀態 何爲嘗試,即需要滿足一定條件,而不是冒然去做某事 188 tryTerminate(); 189 } finally { 190 mainLock.unlock(); 191 } 192 }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章