關(guān)閉線程池 shutdown 和 shutdownNow 的區(qū)別
閱讀本文大概需要 4.5 分鐘。
前言
如何正確關(guān)閉線程池
shutdown 和 shutdownNow 的區(qū)別
項目環(huán)境
jdk 1.8
github 地址:https://github.com/huajiexiewenfeng/java-concurrent
1.線程池示例
public?class?ShutDownThreadPoolDemo?{
????private?ExecutorService?service?=?Executors.newFixedThreadPool(10);
????
????public?static?void?main(String[]?args)?{
????????new?ShutDownThreadPoolDemo().executeTask();
????}
????
????public?void?executeTask()?{
????????for?(int?i?=?0;?i?100;?i++)?{
????????????service.submit(()?->?{
????????????????System.out.println(Thread.currentThread().getName()?+?"->執(zhí)行");
????????????});
????????}
????}
}
pool-1-thread-2->執(zhí)行
pool-1-thread-3->執(zhí)行
pool-1-thread-1->執(zhí)行
pool-1-thread-4->執(zhí)行
pool-1-thread-5->執(zhí)行
pool-1-thread-6->執(zhí)行
...
void shutdown
boolean isShutdown
boolean isTerminated
boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException
List
shutdownNow
2.shutdown
public?void?execute(Runnable?command)?{
????if?(command?==?null)
????????throw?new?NullPointerException();
????int?c?=?ctl.get();
????//?線程池中的線程比核心線程數(shù)少?
????if?(workerCountOf(c)?????????//?新建一個核心線程執(zhí)行任務(wù)
????????if?(addWorker(command,?true))
????????????return;
????????c?=?ctl.get();
????}
????//?核心線程已滿,但是任務(wù)隊列未滿,添加到隊列中
????if?(isRunning(c)?&&?workQueue.offer(command))?{
????????int?recheck?=?ctl.get();
????????//?任務(wù)成功添加到隊列以后,再次檢查是否需要添加新的線程,因為已存在的線程可能被銷毀了
????????if?(!?isRunning(recheck)?&&?remove(command))
????????????//?如果線程池處于非運行狀態(tài),并且把當(dāng)前的任務(wù)從任務(wù)隊列中移除成功,則拒絕該任務(wù)
????????????reject(command);
????????else?if?(workerCountOf(recheck)?==?0)
????????????//?如果之前的線程已經(jīng)被銷毀完,新建一個非核心線程
????????????addWorker(null,?false);
????}
????//?核心線程池已滿,隊列已滿,嘗試創(chuàng)建一個非核心新的線程
????else?if?(!addWorker(command,?false))
????????//?如果創(chuàng)建新線程失敗,說明線程池關(guān)閉或者線程池滿了,拒絕任務(wù)
????????reject(command);
}
3.isShutdown
4.isTerminated
5.awaitTermination
6.shutdownNow
public?List
?shutdownNow()? {
????List?tasks;
????final?ReentrantLock?mainLock?=?this.mainLock;
????mainLock.lock();
????try?{
????????checkShutdownAccess();
????????advanceRunState(STOP);
????????interruptWorkers();
????????tasks?=?drainQueue();
????}?finally?{
????????mainLock.unlock();
????}
????tryTerminate();
????return?tasks;
}
7.shutdown 和 shutdownNow 的區(qū)別?
shutdown 會等待線程池中的任務(wù)執(zhí)行完成之后關(guān)閉線程池,而 shutdownNow 會給所有線程發(fā)送中斷信號,中斷任務(wù)執(zhí)行,然后關(guān)閉線程池
shutdown 沒有返回值,而 shutdownNow 會返回關(guān)閉前任務(wù)隊列中未執(zhí)行的任務(wù)集合(List)
