先说结论,没有完美的线程池关闭方法,因为每个人的业务不同,下面先给出个示例,业务可以在这个基础上修改
下面来看下 guava 提供的线程池关闭方法,我再加些注释
// com.google.common.util.concurrent.MoreExecutors#shutdownAndAwaitTermination public static boolean shutdownAndAwaitTermination( ExecutorService service, long timeout, TimeUnit unit) { // 把阻塞时间平分 long halfTimeoutNanos = unit.toNanos(timeout) / 2 ; // Disable new tasks from being submitted // 这一步是必做的,保证线程池不再接受新的任务 service.shutdown(); try { // Wait for half the duration of the timeout for existing tasks to terminate // 先最多等设置的阻塞时间的一半时间 if (!service.awaitTermination(halfTimeoutNanos, TimeUnit.NANOSECONDS)) { // Cancel currently executing tasks // 考虑到有些任务可能处于阻塞状态,直接 shutdownNow,会中断执行的任务 service.shutdownNow(); // Wait the other half of the timeout for tasks to respond to being cancelled service.awaitTermination(halfTimeoutNanos, TimeUnit.NANOSECONDS); } } catch (InterruptedException ie) { // Preserve interrupt status Thread.currentThread().interrupt(); // (Re-)Cancel if current thread also interrupted service.shutdownNow(); } return service.isTerminated(); } |
线程池的优雅关闭一般情况下就是对 shutdown, shutdownNow ,awaitTermination 的组合使用
但如果对这几个方法理解有偏差,可能造成错误的使用方式,请详细阅读这篇文章 线程池的优雅关闭实践