背景
线程池是日常我们写代码时经常打交道的知识点了,围绕线程池除了core核心线程数和最大max线程数的知识点外,我们一般会忽略然而却绕不开的问题时如何关闭线程池
如何关闭线程池
首先从优雅关闭线程池代码说起:
public boolean grafulShutdown(){
executeService.shutdown();
if (!executeService.awaitTermination(timeout, TimeUnit.MILLISECONDS)) {
executeService.shutdownNow();
if(!executeService.awaitTermination(timeout, TimeUnit.MILLISECONDS)){
return executeService.isTerminated;
}
}
}
第一步:关闭线程池,此时线程不再接受新的任务,并且队列中待执行的任务也会被拒绝掉
executeService.shutdown();
第二步: 等待执行中的线程执行结束,此时线程池中的线程不会收到stop信号的干扰,按部就班的执行
if (!executeService.awaitTermination(timeout, TimeUnit.MILLISECONDS)) {
第三步:等待了很久线程都没有执行完成,此时调用 shutdownNow方法对线程池中正在执行的线程发送stop信号,如果此时线程正在进行socket等操作,会响应stop信号抛出异常,当线程收到异常后,线程中止
executeService.shutdownNow();
}
第四步:继续等待线程池中的线程中止,此时执行中的线程都已经收到stop信号.
executeService.awaitTermination(timeout, TimeUnit.MILLISECONDS)
第五步:返回线程池是否结束的标志,此时你除了知道线程池是否结束之外,也做不了任何事情了.
executeService.isTerminated
这些步骤里面值得注意的就是第三步,当执行线程catch住异常后是如何结束的:
当接收到异常后,线程就会执行processWorkerExit方法减少当前线程数,当线程数减少到0后,就会把线程池状态修改成Terminated状态.