awaitTermination(long timeOut, TimeUnit unit):阻塞线程,等待所有待执行以及正在执行的任务执行完成,或者等到超时,或者线程被中断抛出中断异常,然后返回true或false(表示已超时)。
shutdownNow是立即关闭,而shutdown是优雅关闭。
//这个工具类来自dubbo源码 public class ExecutorUtil { private static final Logger logger = LoggerFactory.getLogger(ExecutorUtil.class); private static final ThreadPoolExecutor shutdownExecutor = new ThreadPoolExecutor(0, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(100), new NamedThreadFactory("Close-ExecutorService-Timer", true)); // 堆代码 duidaima.com public static boolean isTerminated(Executor executor) { if (executor instanceof ExecutorService) { if (((ExecutorService) executor).isTerminated()) { return true; } } return false; } /** * Use the shutdown pattern from: * https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html * @param executor the Executor to shutdown * @param timeout the timeout in milliseconds before termination */ public static void gracefulShutdown(Executor executor, int timeout) { if (!(executor instanceof ExecutorService) || isTerminated(executor)) { return; } final ExecutorService es = (ExecutorService) executor; try { // Disable new tasks from being submitted es.shutdown(); } catch (SecurityException ex2) { return; } catch (NullPointerException ex2) { return; } try { // Wait a while for existing tasks to terminate if (!es.awaitTermination(timeout, TimeUnit.MILLISECONDS)) { es.shutdownNow(); } } catch (InterruptedException ex) { es.shutdownNow(); Thread.currentThread().interrupt(); } if (!isTerminated(es)) { newThreadToCloseExecutor(es); } } public static void shutdownNow(Executor executor, final int timeout) { if (!(executor instanceof ExecutorService) || isTerminated(executor)) { return; } final ExecutorService es = (ExecutorService) executor; try { es.shutdownNow(); } catch (SecurityException ex2) { return; } catch (NullPointerException ex2) { return; } try { es.awaitTermination(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException ex) { Thread.currentThread().interrupt(); } if (!isTerminated(es)) { newThreadToCloseExecutor(es); } } }1 在ServletContextListener接口中销毁
@SpringBootApplication @ServletComponentScan public class ShutdownThreadPoolApplication { public static void main(String[] args) { SpringApplication.run(ShutdownThreadPoolApplication.class, args); } } @WebListener public class ApplicationWatch implements ServletContextListener { private static Logger logger = Logger.getLogger(ArchDataInit.class); public void contextDestroyed(ServletContextEvent event) { logger.info("start ApplicationWatch contextDestroyed method"); logger.info("start shutdown thread pool"); //传入外部定义的线程池executor ExecutorUtil.gracefulShutdown(executor, 20); logger.info("end shutdown thread pool"); }2 在DisposableBean接口中销毁
public class DestroyThreadPoolWhenShutApp implements DisposableBean{ private static Logger logger = Logger.getLogger(DestroyThreadPoolWhenShutApp.class); public void destroy() throws Exception { logger.info("start ApplicationWatch contextDestroyed method"); logger.info("start shutdown thread pool"); //传入外部定义的线程池executor ExecutorUtil.gracefulShutdown(executor, 20); logger.info("end shutdown thread pool"); } }Spring配置文件中创建一个bean级别的销毁bean
<bean id="destroyThreadPool" class="com.demo.spring.DestroyThreadPoolWhenShutApp"/>