Shutdown会启动一个有序的关机过程,在此过程中,之前提交的任务将被执行,但不会接受新的任务。
executor.shutdown()
System.out.println("All tasks submitted...No new tasks will be admitted")
然而,我强烈建议使用awaitTermination,因为这将允许当前线程在关闭请求后阻塞,直到所有任务完成执行,或超时发生,或当前线程被中断,以先发生的为准。
try {
executor.awaitTermination(3, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
编辑:
The runState provides the main lifecyle control, taking on values:
* RUNNING: Accept new tasks and process queued tasks
* SHUTDOWN: Don't accept new tasks, but process queued tasks
* STOP: Don't accept new tasks, don't process queued tasks,
* and interrupt in-progress tasks
* TIDYING: All tasks have terminated, workerCount is zero,
* the thread transitioning to state TIDYING
* will run the terminated() hook method
* TERMINATED: terminated() has completed
这些值之间的数字顺序很重要,以允许有序比较。runState随时间单调递增,但不需要达到每个状态。
转换如下:
RUNNING -> SHUTDOWN
在shutdown()被调用时(可能是finalize()中隐式调用)
(RUNNING或SHUTDOWN) -> STOP
在shutdownNow()被调用时
SHUTDOWN -> TIDYING
当队列和池都为空时
STOP -> TIDYING
当池为空时
TIDYING -> TERMINATED
当terminated()钩子方法完成时。等待awaitTermination()的线程将在状态达到TERMINATED时返回。
检测从SHUTDOWN到TIDYING的转换不太直接,因为在SHUTDOWN状态期间队列可能在非空和空之间变为空,反之亦然,但仅当看到它为空后,我们才能终止并看到workerCount为0。
当你调用getPoolSize()方法时,它会检查线程池处于TIDYING状态时的状态。因此,我认为正确的检查应该是针对TERMINATED状态。尽管如果你没有实现terminated()方法,结果仍然相同。
while loop
在线程池执行完成之前会一直占用 CPU,而awaitTermination
不会如此。2. 当您使用getPoolSize()
时,执行程序的状态尚未终止。尽管您可能还没有实现terminated()
调用,因此您应该没问题。但对于第一个原因,我建议使用awaitTermination
而不是 while 循环。 - Suparna