繁体   English   中英

在Java中关闭ExecutorService的最佳方法

[英]Best way to shutdown ExecutorService in Java

我正在尝试用Java编写异步编程,我正在使用ExecutorService创建一个由多个线程支持的池来提交多个可调用任务,但我对如何关闭ExecutorService几乎没有疑问。

这是我的原始代码:

ExecutorService executorService = Executors.newFixedThreadPool(10);

Future<String> f = executorService.submit(() -> {/*do something*/});

executorService.shutdown();

String result = f.get();
System.out.println(result);

这很好用,执行程序在线程完成后关闭。 但我担心如果写错了可调用任务f.get()的代码永远需要,程序将永远停止并永远不会退出。

有了担心,这是我的第二次尝试:

ExecutorService executorService = Executors.newFixedThreadPool(10);

Future<String> f = executorService.submit(() -> {/*do something*/});

executorService.shutdown();

if(!executorService.awaitTermination(10, TimeUnit.SECONDS)){
    executorService.shutdownNow();
}

String result = f.get();
System.out.println(result);

使用上面的代码,我可以确保线程在10秒后关闭。 但实际上程序被阻止了10秒,线程可能只用了5秒钟。

我的问题是如何设置强制关闭池中的线程的时间,以便我不需要显式使用awaitTermination来阻止程序。

但我担心如果写错了可调用任务f.get()中的代码永远需要,程序将永远停止并永远不会退出。

那是一个错误。 你需要确保不会发生这种情况。

使用上面的代码,我可以确保线程在10秒后关闭

不,你不能。 甚至shutdownNow()实际上并不保证执行程序线程被关闭( 文档 ):

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

ThreadPoolExecutor试图通过中断所有工作线程来“立即关闭”。 您需要确保您的任务正确处理中断

一旦您的任务正确停止,您就可以根据应用程序和正在关闭的任务来估计关闭所需的时间。 然后你可以正常关机:

  • 调用shutdown()
  • 使用awaitShutdown()等待一段合理的时间有序关闭
  • 如果执行程序仍在运行,请调用shutdownNow()并处理它返回的任何未完成的任务。

您的程序不应该在第二个版本中被阻止10秒。 只有当你的线程没有在10秒内终止时,它应该等待10秒。 如果您的线程在10秒内未完成,您的执行程序服务将暂停所有线程的终止。 来自Java文档

/ ** *阻塞,直到所有任务在关闭*请求之后完成执行,或发生超时,或者当前线程被*中断,以先发生者为准。 * * @param超时最长等待时间* @param单位超时参数的时间单位* @return {@code true}如果此执行程序终止,* {@code false}如果超时之前超时* @throws InterruptedException如果在等待时被打断* /

除了上面的答案,我想补充以下几点。

您可以在调用get()方法之前调用Future api的isDone()方法,以验证是否在通过ExcuterService api的awaitTermination方法等待任务完成时完成任务。

但是我建议使用awaitTermination和shutdownNow而不是使用

get(long timeout,TimeUnit unit)[如果需要,最多在给定时间内等待计算完成,然后检索其结果(如果可用)。

未来的API。 如果发生超时,它将抛出TimeoutException,您可能会尝试调用shutdownNow

您还可以通过ExecuterService API的isShutdown()方法检查关闭状态。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM