shutdown和awaitTermination為接口ExecutorService定義的兩個方法,一般情況配合使用來關閉線程池。
方法簡介
shutdown方法:將線程池狀態置為SHUTDOWN。平滑的關閉ExecutorService,當此方法被調用時,ExecutorService停止接收新的任務並且等待已經提交的任務(包含提交正在執行和提交未執行)執行完成。當所有提交任務執行完畢,線程池即被關閉。
awaitTermination方法:接收人timeout和TimeUnit兩個參數,用於設定超時時間及單位。當等待超過設定時間時,會監測ExecutorService是否已經關閉,若關閉則返回true,否則返回false。一般情況下會和shutdown方法組合使用。
shutdownNow方法:將線程池狀態置為STOP。跟shutdown()一樣,先停止接收外部提交的任務,忽略隊列里等待的任務,嘗試將正在跑的任務interrupt中斷,返回未執行的任務列表。
具體實例1
普通任務處理類:
package com.secbro.test.thread; import java.util.concurrent.Callable; /** * @author zhuzhisheng * @Description * @date on 2016/6/1. */ public class Task implements Callable{ @Override public Object call() throws Exception { System.out.println("普通任務"); return null; } }
長時間任務處理類:
package com.secbro.test.thread; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; /** * @author zhuzhisheng * @Description * @date on 2016/6/1. */ public class LongTask implements Callable{ @Override public Object call() throws Exception { System.out.println("長時間任務"); TimeUnit.SECONDS.sleep(5); return null; } }
測試類:
package com.secbro.test.thread; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * @author zhuzhisheng * @Description * @date on 2016/6/1. */ public class TestShutDown { public static void main(String[] args) throws InterruptedException{ ScheduledExecutorService service = Executors.newScheduledThreadPool(4); service.submit(new Task()); service.submit(new Task()); service.submit(new LongTask()); service.submit(new Task()); service.shutdown(); while (!service.awaitTermination(1, TimeUnit.SECONDS)) { System.out.println("線程池沒有關閉"); } System.out.println("線程池已經關閉"); } }
輸出結果為:
普通任務
普通任務
長時間任務
普通任務
線程池沒有關閉
線程池沒有關閉
線程池沒有關閉
線程池沒有關閉
線程池已經關閉
具體實例2
public class ThreadPoolHelper { private static final Logger logger = Logger.getLogger(ThreadPoolHelper.class); private static final int POOL_SIZE = 40;//線程池大小 //訂單任務線程池 private static ThreadPoolExecutor comitTaskPool =(ThreadPoolExecutor) new ScheduledThreadPoolExecutor(POOL_SIZE, new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d").daemon(true).build()); /** * 執行訂單任務 * * @param comitTask */ public static void executeTask(Runnable comitTask) { comitTaskPool.execute(comitTask); logger.debug("【線程池任務】線程池中線程數:" + comitTaskPool.getPoolSize()); logger.debug("【線程池任務】隊列中等待執行的任務數:" + comitTaskPool.getQueue().size()); logger.debug("【線程池任務】已執行完任務數:" + comitTaskPool.getCompletedTaskCount()); } /** * 關閉線程池 */ public static void shutdown() { logger.debug("shutdown comitTaskPool..."); comitTaskPool.shutdown(); try { if (!comitTaskPool.isTerminated()) { logger.debug("直接關閉失敗[" + comitTaskPool.toString() + "]"); comitTaskPool.awaitTermination(3, TimeUnit.SECONDS); if (comitTaskPool.isTerminated()) { logger.debug("成功關閉[" + comitTaskPool.toString() + "]"); } else { logger.debug("[" + comitTaskPool.toString() + "]關閉失敗,執行shutdownNow..."); if (comitTaskPool.shutdownNow().size() > 0) { logger.debug("[" + comitTaskPool.toString() + "]沒有關閉成功"); } else { logger.debug("shutdownNow執行完畢,成功關閉[" + comitTaskPool.toString() + "]"); } } } else { logger.debug("成功關閉[" + comitTaskPool.toString() + "]"); } } catch (InterruptedException e) { logger.warn("接收到中斷請" + comitTaskPool.toString() + "停止操作"); } } }