線(xiàn)程池終止
線(xiàn)程池ThreadPoolExecutor提供了shutdown()和shutDownNow()用于關(guān)閉線(xiàn)程池。
shutdown()后線(xiàn)程池將變成shutdown狀態(tài)雹锣,此時(shí)不接收新任務(wù)洋幻,但會(huì)處理完正在運(yùn)行的 和 在阻塞隊(duì)列中等待處理的任務(wù)。
shutdownNow()后線(xiàn)程池將變成stop狀態(tài)扳剿,此時(shí)不接收新任務(wù)宪郊,不再處理在阻塞隊(duì)列中等待的任務(wù),還會(huì)嘗試中斷正在處理中的工作線(xiàn)程蹭越。
awaitTermination() 等待線(xiàn)程池終止
線(xiàn)程池的終止核心
1 變更線(xiàn)程池的狀態(tài)障本。
2 修改線(xiàn)程池狀態(tài)保證所有work線(xiàn)程能在getTask返回null,導(dǎo)致所有work線(xiàn)程退出
3 針對(duì)因?yàn)楂@取工作隊(duì)列而等待的線(xiàn)程進(jìn)行線(xiàn)程中斷。(工作隊(duì)列阻塞響應(yīng)阻塞)
shutdown
/**
* 溫柔的終止線(xiàn)程池
*/
public void shutdown() {
/** 獲取主鎖:mainLock **/
final ReentrantLock mainLock = this.mainLock;
/** 加鎖 **/
mainLock.lock();
try {
/** 判斷調(diào)用者是否有權(quán)限shutdown線(xiàn)程池 **/
checkShutdownAccess();
/** CAS+循環(huán)設(shè)置線(xiàn)程池狀態(tài)為shutdown **/
advanceRunState(SHUTDOWN);
/** 找到斷線(xiàn)程池中空閑的work响鹃,中斷其工作線(xiàn)程 **/
interruptIdleWorkers();
onShutdown(); // hook for ScheduledThreadPoolExecutor
} finally {
/** 釋放鎖 **/
mainLock.unlock();
}
/** 嘗試將線(xiàn)程池狀態(tài)設(shè)置為T(mén)erminate **/
tryTerminate();
}
shutdownNow
/**
* 強(qiáng)硬的終止線(xiàn)程池
* 返回在隊(duì)列中沒(méi)有執(zhí)行的任務(wù)
*/
public List<Runnable> shutdownNow() {
List<Runnable> tasks;
/** 獲取主鎖:mainLock **/
final ReentrantLock mainLock = this.mainLock;
/** 加鎖 **/
mainLock.lock();
try {
/** 判斷調(diào)用者是否有權(quán)限shutdown線(xiàn)程池 **/
checkShutdownAccess();
/** CAS+循環(huán)設(shè)置線(xiàn)程池狀態(tài)為shutdown **/
advanceRunState(STOP);
/** 找到斷線(xiàn)程池中空閑的work驾霜,中斷其工作線(xiàn)程 **/
interruptWorkers();
tasks = drainQueue();
} finally {
/** 釋放鎖 **/
mainLock.unlock();
}
/** 嘗試將線(xiàn)程池狀態(tài)設(shè)置為T(mén)erminate **/
tryTerminate();
return tasks;
}
檢查調(diào)用者是否有權(quán)限shutdown線(xiàn)程池
/**
* 檢查調(diào)用者是否有權(quán)限shutdown線(xiàn)程池
*/
private void checkShutdownAccess() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(shutdownPerm);
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers)
security.checkAccess(w.thread);
} finally {
mainLock.unlock();
}
}
}
CAS+循環(huán)設(shè)置線(xiàn)程池狀態(tài)為shutdown
/**
* CAS+循環(huán)設(shè)置線(xiàn)程池狀態(tài)為shutdown
*/
private void advanceRunState(int targetState) {
for (;;) {
int c = ctl.get();
if (runStateAtLeast(c, targetState) ||
ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
break;
}
}
找到斷線(xiàn)程池中空閑的work,中斷其工作線(xiàn)程
private void interruptWorkers() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers)
w.interruptIfStarted();
} finally {
mainLock.unlock();
}
}
將workQueue中的元素放入一個(gè)List并返回
**
* 將workQueue中的元素放入一個(gè)List并返回
*/
private List<Runnable> drainQueue() {
BlockingQueue<Runnable> q = workQueue;
ArrayList<Runnable> taskList = new ArrayList<Runnable>();
/** 將隊(duì)列中的值全部從隊(duì)列中移除买置,并賦值給對(duì)應(yīng)集合 **/
q.drainTo(taskList);
/** 并發(fā)在判斷 workQueue是否為空粪糙,將新添加加入到taskList**/
if (!q.isEmpty()) {
for (Runnable r : q.toArray(new Runnable[0])) {
if (q.remove(r))
taskList.add(r);
}
}
return taskList;
}
嘗試將線(xiàn)程池狀態(tài)設(shè)置為T(mén)erminate
/**
* 嘗試將線(xiàn)程池狀態(tài)設(shè)置為T(mén)erminate
*/
final void tryTerminate() {
for (;;) {
int c = ctl.get();
/**
* 判斷線(xiàn)程池能否進(jìn)入TERMINATED狀態(tài)
* 如果以下3中情況任一為true,return堕义,不進(jìn)行終止
* 1猜旬、還在運(yùn)行狀態(tài)
* 2、狀態(tài)是TIDYING倦卖、或 TERMINATED洒擦,已經(jīng)終止過(guò)了
* 3、SHUTDOWN 且 workQueue不為空
* 4
*/
if (isRunning(c) ||
runStateAtLeast(c, TIDYING) ||
(runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
return;
/** 線(xiàn)程池workQueue不為空 return怕膛,并中斷workQueue其中一個(gè)work**/
/**
* 線(xiàn)程池為stop狀態(tài)熟嫩,且還存在work,中斷喚醒一個(gè)正在等任務(wù)的空閑worker,
* 再次調(diào)用getTask(),線(xiàn)程池狀態(tài)發(fā)生改變褐捻,返回null,work工作線(xiàn)程退出循環(huán)
*/
if (workerCountOf(c) != 0) { // Eligible to terminate
interruptIdleWorkers(ONLY_ONE);
return;
}
/** 獲取主鎖:mainLock **/
final ReentrantLock mainLock = this.mainLock;
/** 加鎖 **/
mainLock.lock();
try {
/** 將線(xiàn)程池狀態(tài)設(shè)置為T(mén)IDYING **/
if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
try {
/** 釋放子類(lèi)實(shí)現(xiàn) **/
terminated();
} finally {
/** 將線(xiàn)程池狀態(tài)設(shè)置為T(mén)ERMINATED **/
ctl.set(ctlOf(TERMINATED, 0));
/** 釋放鎖 **/
termination.signalAll();
}
return;
}
} finally {
/** 釋放鎖 **/
mainLock.unlock();
}
// else retry on failed CAS
}
}