讀懂ThreadPoolExecutor執(zhí)行原理克蚂,需要先掌握其狀態(tài)控制的方式俱诸,因?yàn)槭褂昧舜罅课贿\(yùn)算垂攘,讀起來(lái)有點(diǎn)吃力维雇,所以單獨(dú)用一篇文章分析。以下是ThreadPoolExecutor狀態(tài)控制的主要變量和方法:
//原子狀態(tài)控制數(shù)
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
//29比特位
private static final int COUNT_BITS = Integer.SIZE - 3;
//實(shí)際容量 2^29-1
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
// runState is stored in the high-order bits
// runState存儲(chǔ)在高位中
private static final int RUNNING = -1 << COUNT_BITS;
private static final int SHUTDOWN = 0 << COUNT_BITS;
private static final int STOP = 1 << COUNT_BITS;
private static final int TIDYING = 2 << COUNT_BITS;
private static final int TERMINATED = 3 << COUNT_BITS;
// Packing and unpacking ctl 打包和解壓ctl
// 解壓runState
private static int runStateOf(int c) { return c & ~CAPACITY; }
// 解壓workerCount
private static int workerCountOf(int c) { return c & CAPACITY; }
// 打包c(diǎn)tl
private static int ctlOf(int rs, int wc) { return rs | wc; }
線程池使用一個(gè)AtomicInteger的ctl變量將 workerCount(工作線程數(shù)量)和 runState(運(yùn)行狀態(tài))兩個(gè)字段壓縮在一起 晒他,這種做法在在java源碼里經(jīng)常有出現(xiàn)吱型,如在 ReentrantReadWriteLock 里就將一個(gè)int分成高16位和底16位,分別表示讀鎖狀態(tài)和寫(xiě)鎖狀態(tài)陨仅。ThreadPoolExecutor里也是使用了同樣的思想津滞,表現(xiàn)得更加復(fù)雜。
ThreadPoolExecutor用3個(gè)比特位表示runState掂名, 29個(gè)比特位表示workerCount据沈。因此這里需要特別說(shuō)明的是:
確切的說(shuō),當(dāng)最大線程數(shù)量配置為Integer.MXA_VAULE時(shí)饺蔑,ThreadPoolExecutor的線程最大數(shù)量依然是2^29-1锌介。
目前來(lái)看這是完全夠用的,但隨著計(jì)算機(jī)的不斷發(fā)展猾警,真的到了不夠用的時(shí)候可以改變?yōu)锳tomicLong孔祸。這如同32位系統(tǒng)時(shí)間戳?xí)?code>2038年01月19日03時(shí)14分07秒耗盡一樣,當(dāng)以后我們的系統(tǒng)線程能夠超過(guò)2^29-1時(shí)发皿,這些代碼就需要調(diào)整了崔慧。對(duì)于未來(lái),無(wú)限可能穴墅。
思考一下為什么是29:3呢惶室?
這是因?yàn)槲覀兊倪\(yùn)營(yíng)狀態(tài)有5種温自,向上取2次方數(shù),2^3 = 8皇钞。所以必須要3個(gè)比特位來(lái)表示各種狀態(tài)悼泌。
運(yùn)行狀態(tài)解釋:
狀態(tài) | 解釋 |
---|---|
RUNNING | 運(yùn)行態(tài),可處理新任務(wù)并執(zhí)行隊(duì)列中的任務(wù) |
SHUTDOW | 關(guān)閉態(tài)夹界,不接受新任務(wù)馆里,但處理隊(duì)列中的任務(wù) |
STOP | 停止態(tài),不接受新任務(wù)可柿,不處理隊(duì)列中任務(wù)鸠踪,且打斷運(yùn)行中任務(wù) |
TIDYING | 整理態(tài),所有任務(wù)已經(jīng)結(jié)束复斥,workerCount = 0 营密,將執(zhí)行terminated()方法 |
TERMINATED | 結(jié)束態(tài),terminated() 方法已完成 |
整個(gè)ctl的狀態(tài)目锭,會(huì)在線程池的不同運(yùn)行階段進(jìn)行CAS轉(zhuǎn)換卵贱。
多線程系列目錄(不斷更新中):
線程啟動(dòng)原理
線程中斷機(jī)制
多線程實(shí)現(xiàn)方式
FutureTask實(shí)現(xiàn)原理
線程池之ThreadPoolExecutor概述
線程池之ThreadPoolExecutor使用
線程池之ThreadPoolExecutor狀態(tài)控制
線程池之ThreadPoolExecutor執(zhí)行原理
線程池之ScheduledThreadPoolExecutor概述
線程池的優(yōu)雅關(guān)閉實(shí)踐