線程實(shí)現(xiàn)方式
Thread挤渐、Runnable疙渣、Callable
//實(shí)現(xiàn)Runnable接口的類將被Thread執(zhí)行,表示一個(gè)基本任務(wù)
public interface Runnable {
//run方法就是它所有內(nèi)容谣旁,就是實(shí)際執(zhí)行的任務(wù)
public abstract void run();
}
//Callable同樣是任務(wù)阀参,與Runnable接口的區(qū)別在于它接口泛型栋艳,同時(shí)它執(zhí)行任務(wù)候帶有返回值恢准;
//Callable的使用通過外層封裝成Future來使用
public interface Callable<V> {
//相對(duì)于run方法蔗包,call方法帶有返回值
V call() throws Exception;
}
注意:?jiǎn)?dòng)Thread線程只能用start(JNI方法)來啟動(dòng)秉扑,start方法通知虛擬機(jī),虛擬機(jī)通過調(diào)用器映射到底層操作系統(tǒng)调限,通過操作系統(tǒng)來創(chuàng)建線程來執(zhí)行當(dāng)前任務(wù)的run方法
Executor框架
Executor接口是線程池框架中最基礎(chǔ)的部分舟陆,定義了一個(gè)用于執(zhí)行Runnable的execute方法。從圖中可以看出Exectuor下有一個(gè)重要的子接口ExecutorService旧噪,其中定義了線程池的具體行為:
execute(Runnable runnable):執(zhí)行Runnable類型的任務(wù)
submit(task):用來提交Callable或者Runnable任務(wù)吨娜,并返回代表此任務(wù)的Future對(duì)象
shutdown():在完成已經(jīng)提交的任務(wù)后封閉辦事,不在接管新的任務(wù)
shutdownNow():停止所有正在履行的任務(wù)并封閉辦事
isTerminated():是一個(gè)鉤子函數(shù)淘钟,測(cè)試是否所有任務(wù)都履行完畢了
isShutdown():是一個(gè)鉤子函數(shù)宦赠,測(cè)試是否該ExecutorService是否被關(guān)閉
ExecutorService中的重點(diǎn)屬性:
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
ctl:對(duì)線程池的運(yùn)行狀態(tài)和線程池中有效線程的數(shù)量進(jìn)行控制的一個(gè)字段,它包含兩部分信息:線程池的運(yùn)行狀態(tài)(runState)和線程池內(nèi)有效線程的數(shù)量(workerCount)米母。
這里可以看到勾扭,使用Integer類型來保存,高3位保存runState铁瞒,低29位保存workerCount妙色。COUNT_BITS 就是29,CAPACITY 就是1左移29位減1(29個(gè)1)慧耍,這個(gè)常量表示workerCount的上限值身辨,大約是5億。
ctl相關(guān)方法:
//獲取運(yùn)行狀態(tài)
private static int runStateOf(int c){
return c & ~CAPACITY;
}
//獲取活動(dòng)線程數(shù)
private static int workerCountOf(int c) {
return c & CAPACITY;
}
//獲取運(yùn)行狀態(tài)和活動(dòng)線程數(shù)的值
private static int ctlOf(int rs, int wc) {
return rs | wc;
}
線程池的狀態(tài):
RUNNING = -1 << COUNT_BITS? //高3位為111
SHUTDOWN = 0 << COUNT_BITS? //高3位為000
STOP = 1 << COUNT_BITS? //高3位為001
TIDYING = 2 << COUNT_BITS? //高3位為010
TERMINATED = 3 << COUNT_BITS? //高3位為011
線程池實(shí)例的狀態(tài)
1芍碧、RUNNING
- 狀態(tài)說明:線程池處于RUNNING狀態(tài)煌珊,能夠接收新任務(wù),以及對(duì)已添加的任務(wù)進(jìn)行處理泌豆。
- 狀態(tài)切換:線程池的初始化狀態(tài)是RUNNING定庵。換句話說,線程池一旦被創(chuàng)建踪危,就處于RUNNING狀態(tài)蔬浙,并且線程池中的任務(wù)數(shù)為0。
2贞远、SHUTDOWN
- 狀態(tài)說明:線程池處于SHUTDOWN狀態(tài)畴博,不接收新任務(wù),能夠處理已經(jīng)添加的任務(wù)蓝仲。
- 狀態(tài)切換:調(diào)用shutdown()方法時(shí)俱病,線程池由RUNNING -> SHUTDOWN蜜唾。
3、STOP
- 狀態(tài)說明:線程池處于STOP狀態(tài)庶艾,不接收新任務(wù)袁余,不處理已提交的任務(wù),并且會(huì)中斷正在處理的任務(wù)咱揍。
- 狀態(tài)切換:調(diào)用線程池中的shutdownNow()方法時(shí)颖榜,線程池由(RUNNING or SHUTDOWN) -> STOP。
4煤裙、TIDYING
- 狀態(tài)說明:當(dāng)所有的任務(wù)已經(jīng)停止掩完,ctl記錄“任務(wù)數(shù)量”為0,線程池會(huì)變?yōu)門IDYING狀態(tài)硼砰。當(dāng)線程池處于TIDYING狀態(tài)時(shí)且蓬,會(huì)執(zhí)行鉤子函數(shù) terminated()。terminated()在ThreadPoolExecutor類中是空题翰, 的恶阴,若用戶想在線程池變?yōu)門IDYING時(shí),進(jìn)行相應(yīng)處理豹障,可以通過重載 terminated()函數(shù)來實(shí)現(xiàn)冯事。
- 狀態(tài)切換:當(dāng)線程池在SHUTDOWN狀態(tài)下,阻塞隊(duì)列為空并且線程池中執(zhí)行任務(wù)也為空時(shí)血公,就會(huì)由SHUTDOWN -> TIDYING昵仅。當(dāng)線程池在STOP狀態(tài)下,線程池中執(zhí)行的任務(wù)為空時(shí)累魔,就會(huì)由STOP-> TIDYING摔笤。
5、TERMINATED
- 狀態(tài)說明:線程池線程池徹底停止垦写,線程池處于TERMINATED狀態(tài)吕世,
- 狀態(tài)切換:線程池處于TIDYING狀態(tài)時(shí),執(zhí)行完terminated()之后梯澜, 就會(huì)由TIDYING->TERMINATED寞冯。
線程池使用
ThreadPoolExecutor構(gòu)造方法
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
任務(wù)的提交流程
執(zhí)行圖: