如果在线程执行器上调用shutdown()
失败,将导致应用程序永远不会终止。
关闭ExecutorService的最佳做法是:
ExecutorService service = null;
try {
service = Executors.newSingleThreadExecutor();
// add tasks to thread executor
…
} finally {
if (service != null) service.shutdown();
}
既然Java知道资源尝试的概念,如果我们能做到这一点,那不是很好吗?
try (service = Executors.newSingleThreadExecutor())
{
// add tasks to thread executor
…
}
4条答案
按热度按时间3wabscal1#
那个ExecutorService其实有两个关机相关的方法;基于一个简单的事实,即关闭服务的两种方式都有意义。
因此:你将如何自动关闭一个服务呢?以一种对每个人都有效的一致方式?!
所以,我眼中的合理解释:你不能使ExecutorService成为AutoClosable,因为该服务没有一个类似“close”的操作;而是两个!
如果你认为你可以很好地利用这样一个自动关闭服务,那么使用“委托”编写你自己的实现将是一件5分钟的事情!或者可能是10分钟,因为你将创建一个调用
shutdown()
作为关闭操作的版本;一个是shutdownNow()
yxyvkwin2#
这是一个平庸的变通方法
或者,如果检查的异常困扰你,你可以这样写:
然后
当然,绝对不能在赋值语句和
try
语句之间放置任何东西,也不能在try
语句之后使用service
局部变量。考虑到这些警告,只需使用
finally
即可。h7wcgrx33#
ExeuctorService
是Java 19+中的AutoCloseable
在Java 19中,
ExeuctorService
现在实现了AutoCloseable
。默认实现调用
shutdown()
并等待awaitTermination
完成任务(1天)。如果中断,则调用shutdownNow()
。谷歌Guava
对于早期的Java,您可以使用Guava's
ForwardingExecutorService
将ExeuctorService
装饰为AutoCloseable
:6yjfywim4#
我看不出AutoCloseable对Executor有什么用。try-with-resources是用于可以在方法范围内初始化,使用和释放的东西。这对于文件,网络连接,jdbc资源等非常有用,它们可以快速打开,使用和清理。但是Executor,特别是线程池,是你想要长时间可用的东西。可能在应用程序的生命周期内,并且倾向于注入到诸如单例服务之类的东西中,这些服务可以有一个方法,DI框架知道在应用程序关闭时调用该方法来清理执行器。这种使用模式在没有尝试资源的情况下工作得很好。
另外,try-with-resources背后的一个重要动机是确保异常不会被屏蔽。这不是执行器需要考虑的问题,所有的异常抛出都将发生在提交给执行器的任务中,异常屏蔽不是问题。