ExecutorService shutdownNow 不会关闭 JVM



正在学习Java 1.5中引入的ExecutorService

以下示例似乎违背了预期的行为:

public static void main(String[] args) throws InterruptedException,
ExecutionException,TimeoutException  {

Callable<String> task = () -> {
int counter = 0;
while(true) {
//infinite loop will never exit
if(counter == 7) {
break;
}
}
return "abc";
};

ExecutorService service = Executors.newSingleThreadExecutor();          
try {
Future<String> future = service.submit(task);

System.out.println("result = " + future.get(10000,TimeUnit.MILLISECONDS));
}finally {
System.out.println("<<<< finally >>>>");
service.shutdownNow();
}



}

查看此方法的 java 文档:

尝试停止所有活动正在执行的任务,停止对等待任务的处理,并返回等待执行的任务的列表。

此方法不会等待主动执行的任务终止。使用 awaitTerminate 来执行此操作。

除了尽力尝试停止处理主动执行的任务之外,没有任何保证。例如,典型的实现将通过 Thread.break 取消,因此任何无法响应中断的任务都可能永远不会终止。

因此,理想情况下,我所期望的是,在指定的超时后,我将收到超时异常,然后执行器服务将强制关闭,但这不会发生。

查看了java文档 - 它似乎确实表明无法保证它会关闭。

如果不能保证,那么应该避免吗?

查看了java文档 - 它似乎确实表明无法保证它会关闭。

正确。

如果不能保证,那么应该避免吗?

不。

您实际上应该做的是以避免或绕过限制的方式使用ExecutorService;例如

  • 实现任何可能长时间运行且可终止的任务,以便它们正确处理中断。 如果您正确执行此操作,那么您ExecutorService将终止。

  • 不要依赖实际关闭ExecutorService。 例如,您可以安排当应用程序需要关闭时,它会执行以下操作:

    1. 它调用shutdownNow()
    2. 它使用适当的超时调用awaitTermination(...)
    3. 如果ExecutorService未终止,则调用System.exit(...)来终止应用程序。
  • 配置ExecutorService以将工作线程创建为守护程序线程;请参阅在 Java 中将执行程序服务转换为守护程序。

    守护进程线程不会阻止 JVM 退出。 但请注意,您需要小心。 如果所有非守护进程线程都已完成,JVM 将拔掉插头,而不会中断ExecutorService当前正在运行的任何任务。

相关内容

  • 没有找到相关文章

最新更新