Why does the ExecutorService interface not implement AutoCloseable?
This is a mediocre workaround
ExecutorService service = Executors.newSingleThreadExecutor();
try (Closeable close = service::shutdown) {
}
Or, if the checked exception bothers you, you could write:
interface MyCloseable extends AutoCloseable {
void close();
}
And then
ExecutorService service = Executors.newSingleThreadExecutor();
try (MyCloseable close = service::shutdown) {
}
Of course, you must never ever put anything between the assignment and the try
statement, nor use the service
local variable after the try
statement.
Given the caveats, just use finally
instead.
I don't see where AutoCloseable is that useful for an Executor. try-with-resources is for things that can be initialized, used, and released within the scope of a method. This works great for things like files, network connections, jdbc resources, etc., where they get opened, used, and cleaned up quickly. But an executor, especially a threadpool, is something you want available for a long time period, probably over the lifetime of the application, and will tend to get injected into things like singleton services, which can have a method that the DI framework knows to call on application shutdown to clean up the executor. This usage pattern works fine without try-with-resources.
Also, a big motivator behind try-with-resources is making sure exceptions don't get masked. That's not a consideration so much with executors, all the exception-throwing will be happening in the tasks submitted to the executor, exception-masking is not an issue.
That ExecutorService has actually two shutdown-related methods; based on the simple fact that both ways of shutting down a service make sense.
Thus: how would you auto-close a service then? In a consistent manner that works for everybody?!
So, the reasonable explanation in my eyes: you can't make an ExecutorService a AutoClosable because that service does not have a single "close" like operation; but two!
And if you think you could make good use of such an auto-closing service, writing up your own implementation using "delegation" would be a 5 minute thing! Or probably 10 minutes, because you would create one version calling shutdown()
as close operation; and one that does shutdownNow()
instead.