线程池的生命周期
我们都知道线程的生命周期,可分为几种状态。同样,线程池也一样:通过查看ThreadPoolExecutor类源码,我们可以看到定义了5种线程池状态:
这几种状态的转换过程看下图
说线程池的状态转换就要提到线程池中几个方法:
线程池Executor是异步的执行任务,因此任何时刻不能够直接获取提交的任务的状态。这些任务有可能已经完成,也有可能正在执行或者还在排队等待执行。因此关闭线程池可能出现一下几种情况:
平缓关闭:已经启动的任务全部执行完毕,同时不再接受新的任务. java.util.concurrent.ExecutorService#shutdown
立即关闭:取消所有正在执行和未执行的任务 .java.util.concurrent.ExecutorService#shutdownNow
1、线程池在构造前(new操作)是初始状态,一旦构造完成线程池就进入了执行状态RUNNING。严格意义上讲线程池构造完成后并没有线程被立即启动,只有进行“预启动”或者接收到任务的时候才会启动线程。这个在上一篇文章中已经作了介绍并配合代码分析验证。但是线程池是出于运行状态,随时准备接受任务来执行。
2、线程池运行中可以通过shutdown()和shutdownNow()来改变运行状态。shutdown()是一个平缓的关闭过程,线程池停止接受新的任务,同时等待已经提交的任务执行完毕,包括那些进入队列还没有开始的任务,这时候线程池处于SHUTDOWN状态;shutdownNow()是一个立即关闭过程,线程池停止接受新的任务,同时线程池取消所有执行的任务和已经进入队列但是还没有执行的任务,这时候线程池处于STOP状态。
3、一旦shutdown()或者shutdownNow()执行完毕,线程池就进入TERMINATED状态,此时线程池就结束了。
isTerminated()描述的是TERMINATED状态。
isShutdown()描述的是非RUNNING状态,也就是SHUTDOWN/STOP/TERMINATED三种状态。
查看源码我们发现shutdownNow会返回那些已经进入了队列但是还没有执行的任务列表
awaitTermination描述的是等待线程池关闭的时间,如果等待时间线程池还没有关闭将会抛出一个超时异常。
前面一开始我们在源码中就看到了TIDYING状态,那么这个状态表示什么阶段呢?我们继续看源码,在源码中有这么一段注释:
看源码中其实已经描述的很清楚了,其实就是线程池在SHUTDOWM/STOP到TERMINATED状态之间还存在一个TIDYING状态
总结以上:
这几个状态的转化关系为:
1、调用shundown()方法线程池的状态由RUNNING——>SHUTDOWN
2、调用shutdowNow()方法线程池的状态由RUNNING——>STOP
3、当任务队列和线程池均为空的时候 线程池的状态由STOP/SHUTDOWN——–>TIDYING
4、当terminated()方法被调用完成之后,线程池的状态由TIDYING———->TERMINATED状态
关于线程中状态切换后面也会在代码中展示,有兴趣的小伙伴请持续关注。。。
参考博文:
https://blog.csdn.net/u010412719/article/details/52132601