如果不能在线程执行器上调用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
…
} 发布于 2016-12-30 09:03:23
ExecutorService实际上有两个与关闭相关的方法;基于这样一个简单的事实:和都有关闭服务的方式是有意义的。
因此:您将如何自动关闭一项服务?以一种对每个人都有效的一致方式?!
因此,在我看来,合理的解释是:您不能让ExecutorService成为一个AutoClosable,因为该服务没有一个类似于“关闭”的操作;而是两个!
如果你认为你能很好地利用这样的自动关闭服务,用“委托”编写你自己的实现将是一件5分钟的事情!或者大约10分钟,因为您将创建一个版本,将shutdown()称为close操作;而另一个版本则调用shutdownNow()。
发布于 2016-12-30 11:20:07
这是一个平庸的解决办法。
ExecutorService service = Executors.newSingleThreadExecutor();
try (Closeable close = service::shutdown) {
}或者,如果检查的异常困扰您,您可以写:
interface MyCloseable extends AutoCloseable {
void close();
}然后
ExecutorService service = Executors.newSingleThreadExecutor();
try (MyCloseable close = service::shutdown) {
}当然,您绝不能在赋值和try语句之间放置任何内容,也不能在try语句之后使用service局部变量。
考虑到这些警告,只需使用finally即可。
发布于 2016-12-30 18:01:20
我看不出AutoCloseable对执行者有什么用处。在方法的范围内,可以初始化、使用和释放的东西都可以尝试使用资源。这对于文件、网络连接、jdbc资源等都非常有用,在这些资源中,它们会被快速打开、使用和清理。但是,执行器,特别是线程池,是您希望在很长一段时间内(可能在应用程序的生存期内)可用的东西,并且可能会被注入到诸如singleton服务之类的东西中,这些服务可以有DI框架知道的方法,在应用程序关闭时调用它来清理执行器。这种使用模式在不使用资源的情况下运行良好。
此外,资源尝试背后的一个重要动机是确保例外情况不会被掩盖。对于执行者来说,这不是一个考虑因素,所有的异常抛出都会发生在提交给执行者的任务中,异常掩蔽不是一个问题。
https://stackoverflow.com/questions/41393417
复制相似问题