線程池狀態和工作線程數–ctl
ctl屬性的設計原理
ctl屬性是一個Integer原子變量,用於記錄線程狀態和線程池中線程數量。Integer變量的高3位記錄線程狀態,剩餘位記錄線程池線程個數。
// ctl屬性:默認爲RUNNING
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3; // 29位
// 00011111 11111111 11111111 11111111
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
// runState--高3位
private static final int RUNNING = -1 << COUNT_BITS; // 11100000 00000000 00000000 00000000
private static final int SHUTDOWN = 0 << COUNT_BITS; // 00000000 00000000 00000000 00000000
private static final int STOP = 1 << COUNT_BITS; // 00100000 00000000 00000000 00000000
private static final int TIDYING = 2 << COUNT_BITS; // 01000000 00000000 00000000 00000000
private static final int TERMINATED = 3 << COUNT_BITS; // 01100000 00000000 00000000 00000000
// Packing and unpacking ctl
private static int runStateOf(int c) { return c & ~CAPACITY; } // 池狀態
private static int workerCountOf(int c) { return c & CAPACITY; } // 工作線程數
private static int ctlOf(int rs, int wc) { return rs | wc; } // 當前ctl值
線程池的5個狀態與狀態切換
ctl屬性的高3位,提供了線程池的運行狀態,包含線程池主要生命週期。
- RUNNING:接受新任務,並且可以處理阻塞隊列中的任務。
- SHUTDOWN:拒絕新任務,但可以處理隊列中的任務。
- STOP:拒絕新任務,拋棄隊列中的任務,中斷正在處理的任務。
- TIDYING:所有任務都已終止,工作線程數爲0,此時切換爲TIDYING狀態,將要調用terminated()鉤子方法(默認不做任何事情)。
- TERMINATED:terminated()調用完成後的狀態。
5種狀態是數字有序的,可以直接進行數值比較。例如,isRunning()方法。
線程池狀態的切換
其他屬性
// 線程池完成任務計數器。在woker線程退出時統計,統計過程加mainLock鎖
private long completedTaskCount;
// woker線程保持存活的最小數量
// 如果allowCoreThreadTimeOut值爲true,則最小存活線程數是0
private volatile int corePoolSize;
// 最大線程數
private volatile int maximumPoolSize;
// 空閒線程等待任務的超時時間
// 大於coreThreadSize的線程和allowCoreThreadTimeOut值爲true的核心線程會用到超時。其他會永久阻塞等待
private volatile long keepAliveTime;
// 核心線程是否可以超時
// 默認是false,即核心線程即使空閒仍然保持存活;如果值爲true,核心線程使用keepAliveTime去超時等待獲取隊列任務。
private volatile boolean allowCoreThreadTimeOut;
// 線程池飽和,或者執行過程中shutdown,調用拒絕策略。參見execute方法。
private volatile RejectedExecutionHandler handler;
// 生產新線程的工廠,默認是DefaultThreadFactory(參見addWorker和Worker構造器)
private volatile ThreadFactory threadFactory;
// 任務隊列
private final BlockingQueue<Runnable> workQueue;
// 最大可以獲取的線程數。更新過程加鎖。 告訴外部此時線程池能獲取的最大線程數
private int largestPoolSize;
// 默認的拒絕策略是AbortPolicy,拒絕任務拋異常
private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();
// 全局鎖
private final ReentrantLock mainLock = new ReentrantLock();
// mainLock的等待狀態
private final Condition termination = mainLock.newCondition();
// 線程池woker線程的集合。對wokers的操作需要持有mainLock鎖
private final HashSet<Worker> workers = new HashSet<Worker>();