Java工程師知識(shí)樹(shù) / Java基礎(chǔ)
線程實(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的使用通過(guò)外層封裝成Future來(lái)使用
public interface Callable<V> {
//相對(duì)于run方法,call方法帶有返回值
V call() throws Exception;
}
注意:?jiǎn)?dòng)Thread線程只能用start(JNI方法)來(lái)啟動(dòng),start方法通知虛擬機(jī),虛擬機(jī)通過(guò)調(diào)用器映射到底層操作系統(tǒng),通過(guò)操作系統(tǒng)來(lái)創(chuàng)建線程來(lái)執(zhí)行當(dāng)前任務(wù)的run方法
Executor框架
Executor接口是線程池框架中最基礎(chǔ)的部分,定義了一個(gè)用于執(zhí)行Runnable的execute方法。從圖中可以看出Exectuor下有一個(gè)重要的子接口ExecutorService,其中定義了線程池的具體行為:
execute(Runnable runnable):執(zhí)行Runnable類型的任務(wù)
submit(task):用來(lái)提交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類型來(lái)保存,高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)說(shuō)明:線程池處于RUNNING狀態(tài),能夠接收新任務(wù),以及對(duì)已添加的任務(wù)進(jìn)行處理。
- 狀態(tài)切換:線程池的初始化狀態(tài)是RUNNING。換句話說(shuō),線程池一旦被創(chuàng)建,就處于RUNNING狀態(tài),并且線程池中的任務(wù)數(shù)為0。
2、SHUTDOWN
- 狀態(tài)說(shuō)明:線程池處于SHUTDOWN狀態(tài),不接收新任務(wù),能夠處理已經(jīng)添加的任務(wù)。
- 狀態(tài)切換:調(diào)用shutdown()方法時(shí),線程池由RUNNING -> SHUTDOWN。
3、STOP
- 狀態(tài)說(shuō)明:線程池處于STOP狀態(tài),不接收新任務(wù),不處理已提交的任務(wù),并且會(huì)中斷正在處理的任務(wù)。
- 狀態(tài)切換:調(diào)用線程池中的shutdownNow()方法時(shí),線程池由(RUNNING or SHUTDOWN) -> STOP。
4、TIDYING
- 狀態(tài)說(shuō)明:當(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)處理,可以通過(guò)重載 terminated()函數(shù)來(lái)實(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)說(shuō)明:線程池線程池徹底停止,線程池處于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í)行圖:

