1. 程式人生 > 其它 >執行緒池的狀態及其處理的技巧

執行緒池的狀態及其處理的技巧

執行緒池的狀態及其處理的技巧

執行緒的狀態

執行緒池有5種狀態:

  • Running,:執行緒池處在RUNNING狀態時,能夠接收新任務,以及對已新增的任務進行處理

  • SHUTDOWN,:執行緒池處在SHUTDOWN狀態時,不接收新任務,但能處理已新增的任務

  • STOP,:執行緒池處在STOP狀態時,不接收新任務,不處理已新增的任務,並且會中斷正在處理的任務

  • TIDYING:當所有的任務已終止,ctl記錄的"任務數量"為0,執行緒池會變為TIDYING狀態。當執行緒池變為TIDYING狀態時,會執行鉤子函式terminated()。

    • 例如:當執行緒池在SHUTDOWN狀態下,阻塞佇列為空並且執行緒池中執行的任務也為空時,就會由 SHUTDOWN -> TIDYING
  • TERMINATED:執行緒池徹底終止,就變成TERMINATED狀態

執行緒池的狀態量
1 private static final int RUNNING    = -1 << COUNT_BITS;	-- 對應的高3位值是111。
2 private static final int SHUTDOWN   =  0 << COUNT_BITS;	-- 對應的高3位值是000。
3 private static final int STOP       =  1 << COUNT_BITS;	-- 對應的高3位值是001。
4 private static final int TIDYING    =  2 << COUNT_BITS;	-- 對應的高3位值是010。
5 private static final int TERMINATED =  3 << COUNT_BITS;	-- 對應的高3位值是011。

執行緒池使用一個原子整型來控制執行緒池的狀態:

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
  • ctl是原子整形,cas鎖,操作具有原子、有序、可見性

  • ctl分為兩個組成部分,一個是runState(執行緒池狀態),一個是workerCount(工作執行緒數)

  • ctlof將兩個狀態進行打包:

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

    因為連個狀態佔據的是高3位和低29位所以不會衝突

狀態獲取
1 //拆包函式
2 private static int runStateOf(int c)     { return c & ~CAPACITY; }
3 private static int workerCountOf(int c)  { return c & CAPACITY; }
4 //打包函式
5 private static int ctlOf(int rs, int wc) { return rs | wc; }

主要通過COUNT_BITSCAPACITY獲取狀態

1 private static final int COUNT_BITS = Integer.SIZE - 3;
2 private static final int CAPACITY   = (1 << COUNT_BITS) - 1;