优雅关闭线程池
Posted go大鸡腿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了优雅关闭线程池相关的知识,希望对你有一定的参考价值。
前言
这一类的文章在公众号其实是很多的,所以这一篇主要是加深自己对线程池的相关函数以及关闭线程池的知识点进行总结~
why?
为啥会出现如何优雅关闭线程池这类问题?比如说线程池还在执行任务,这时jvm就关闭了,很多任务是直接out对吧。所以说如何解决这个问题。
how?
RunTime.getRunTime().addShutdownHook
新增一个关闭回调钩子,就是在jvm关闭的时候会进行回调。
其次,如果是你去完成关闭线程池的功能你会怎么设计呢?
PS:之前面阿里的时候,有个小组leader说我还有一些细节的东西没有了解全面,但是…很多东西原理都是互通的,比如说网关,nginx转发等等,跟gateway还有dubbo转发原理是一样的,正所谓大道至简~
那我们设计的话:
- 超时关闭,这个等待时间是没有人知道的,像接口超时有些固定5秒,10秒,20秒
- 会记录下丢失的任务线程id
- 打印相关的日志
相关参数
这里以ExecutorService为例
shutdowm
启动有序关闭,其中执行先前提交的任务,但不会接受新任务。如果已经关闭,调用没有额外的效果。 此方法不等待先前提交的任务完成执行。使用 awaitTermination 来做到这一点。
shutdownNow
尝试停止所有正在执行的任务,停止等待任务的处理,并返回等待执行的任务列表。 此方法不会等待主动执行的任务终止。使用 awaitTermination 来做到这一点。 除了尽力尝试停止处理正在执行的任务之外,没有任何保证。例如,典型的实现将通过 Thread.interrupt() 取消,因此任何未能响应中断的任务可能永远不会终止。 返回: 从未开始执行的任务列表
所以这个方法是可以返回未开始执行的任务列表,也就是打印相关还未执行的线程。
shutdown跟shutdownNow区别
shutdownNow会主动去尝试终止正在进行的任务,而shutdown只是不再接受新的任务
具体关闭线程池代码
The following method shuts down an ExecutorService in two phases, first by calling shutdown to reject incoming tasks, and then calling shutdownNow, if necessary, to cancel any lingering tasks:
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
当然这只是个demo,如果你觉得像接口重试,或者连接超时那样,只要超过特定时间就抛出异常,也可以,等待完直接shutdownNow,会有点暴力。
参考资料
以上是关于优雅关闭线程池的主要内容,如果未能解决你的问题,请参考以下文章