ThreadPoolExecutor原始碼分析(一):重要成員變數
ThreadPoolExecutor是一個通過使用可能幾個池執行緒之一來執行每個提交任務的ExecutorService,這些執行緒池通常通過Executors工廠方法進行配置。
ThreadPoolExecutor中的執行緒池處理了兩個不同的問題:
1、由於減少了每個任務呼叫的開銷,在執行大量的非同步任務時它們通常提供改進的效能;
2、它們提供了邊界和管理資源的一種手段,包括多執行緒,在執行任務集合時的消耗。
每個ThreadPoolExecutor還維護一些基本的統計資料,例如完成任務的數量。
一、ThreadPoolExecutor中的重要成員變數
1、AtomicInteger ctl
AtomicInteger型別的ctl代表了ThreadPoolExecutor中的控制狀態,它是一個複核型別的成員變數,是一個原子整數,藉助高低位包裝了兩個概念:
(1)workerCount:執行緒池中當前活動的執行緒數量,佔據ctl的低29位;
(2)runState:執行緒池執行狀態,佔據ctl的高3位,有RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED五種狀態。
AtomicInteger ctl的定義如下:
- privatefinal AtomicInteger ctl =
先說下workerCount:執行緒池中當前活動的執行緒數量,它佔據ctl的低29位,這樣,每當活躍執行緒數增加或減少時,ctl直接做相應數目的增減即可,十分方便。而ThreadPoolExecutor中COUNT_BITS就代表了workerCount所佔位數,定義如下:
- privatestaticfinalint COUNT_BITS = Integer.SIZE - 3;
它肯定有個上下限閾值,下限很明顯就是0,上限呢?ThreadPoolExecutor中CAPACITY就代表了workerCount的上限,它是ThreadPoolExecutor中理論上的最大活躍執行緒數,其定義如下:
- private
既然workerCount作為其中一個概念複合在AtomicInteger ctl中,那麼ThreadPoolExecutor理應提供從AtomicInteger ctl中解析出workerCount的方法,如下:
- privatestaticint workerCountOf(int c) { return c & CAPACITY; }
接下來,我們再看下runState:執行緒池執行狀態,它佔據ctl的高3位,有RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED五種狀態。我們先分別解釋下這五種狀態:
(1)RUNNING:接受新任務,並處理佇列任務
- privatestaticfinalint RUNNING = -1 << COUNT_BITS;
(2)SHUTDOWN:不接受新任務,但會處理佇列任務
- privatestaticfinalint SHUTDOWN = 0 << COUNT_BITS;
(3)STOP:不接受新任務,不會處理佇列任務,而且會中斷正在處理過程中的任務
- privatestaticfinalint STOP = 1 << COUNT_BITS;
1在Java底層是由前面的31個0和1個1組成的,左移29位的話,即001 00000 00000000 00000000 00000000,也就是低29位全部為0,高3位為001的話,表示STOP狀態,即536870912;
(4)TIDYING:所有的任務已結束,workerCount為0,執行緒過渡到TIDYING狀態,將會執行terminated()鉤子方法
- privatestaticfinalint TIDYING = 2 << COUNT_BITS;
(5)TERMINATED:terminated()方法已經完成
- privatestaticfinalint TERMINATED = 3 << COUNT_BITS;
由上面我們可以得知,執行狀態的值按照RUNNING-->SHUTDOWN-->STOP-->TIDYING-->TERMINATED順序值是遞增的,這些值之間的數值順序很重要。隨著時間的推移,執行狀態單調增加,但是不需要經過每個狀態。那麼,可能存在的執行緒池狀態的轉換是什麼呢?如下:
(1)RUNNING -> SHUTDOWN:呼叫shutdownNow()方法後,或者執行緒池實現了finalize方法,在裡面呼叫了shutdown方法,即隱式呼叫;
(2)(RUNNING or SHUTDOWN) -> STOP:呼叫shutdownNow()方法後;
(3)SHUTDOWN -> TIDYING:執行緒池和佇列均為空時;
(4)STOP -> TIDYING:執行緒池為空時;
(5)TIDYING -> TERMINATED:terminated()鉤子方法完成時。
我們再來看下是實現獲取執行狀態的runStateOf()方法,程式碼如下:
- privatestaticint runStateOf(int c) { return c & ~CAPACITY; }
最後,我們再看下原子變數ctl的初始化方法ctlOf(),程式碼如下:
- privatestaticint ctlOf(int rs, int wc) { return rs | wc; }
2、BlockingQueue<Runnable> workQueue
workQueue是用於持有任務並將其轉換成工作執行緒worker的佇列;
3、HashSet<Worker> workers
workers是包含執行緒池中所有工作執行緒worker的集合,僅僅當擁有mainLock鎖時才能訪問它;
4、long completedTaskCount
completedTaskCount是已完成任務的計數器,只有在worker執行緒的終止,僅僅當擁有mainLock鎖時才能訪問它;
5、volatile ThreadFactory threadFactory
建立新執行緒的工廠類;
6、volatile RejectedExecutionHandler handler
執行過程中shutdown時呼叫的handler;
7、volatile long keepAliveTime
空閒執行緒等待工作的超時時間(納秒),即空閒執行緒存活時間;
8、volatile boolean allowCoreThreadTimeOut
預設值為false,如果為false,core執行緒在空閒時依然存活;如果為true,則core執行緒等待工作,直到時間超時至keepAliveTime;
9、volatile int corePoolSize
核心執行緒池大小,保持存活的工作執行緒的最小數目,當小於corePoolSize時,會直接啟動新的一個執行緒來處理任務,而不管執行緒池中是否有空閒執行緒;
10、volatile int maximumPoolSize
執行緒池最大大小,也就是執行緒池中執行緒的最大數量。