Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the ExecutorService interface not implement AutoCloseable?

Failing to call shutdown() on a thread executor will result in a never terminating application.

Best practice to shut down the ExecutorService is this:

ExecutorService service = null;
try {
  service = Executors.newSingleThreadExecutor();
  // add tasks to thread executor
  …
} finally {
  if (service != null) service.shutdown();
}

Since Java knows the try-with-resources concept, wouldn't it be nice if we could do this?

try (service = Executors.newSingleThreadExecutor())
{
  // add tasks to thread executor
  …
} 
like image 280
Adrian Krebs Avatar asked Dec 30 '16 09:12

Adrian Krebs


People also ask

Does executor implement AutoCloseable?

Since the ExecutorService class does not implement the AutoCloseable interface, we need to wrap it with something that does. Then, we call the ExecutorService. shutdown method within the close method from the AutoCloseable interface. If we don't implement the AutoCloseable interface, we'll get compile-time errors.

Can Callables be submitted to ExecutorService?

The Runnable interface represents a task that can be executed concurrently by a thread or an ExecutorService . The Callable can only be executed by an ExecutorService.

What is difference between closeable and AutoCloseable?

Closeable extends IOException whereas AutoCloseable extends Exception. Closeable interface is idempotent (calling close() method more than once does not have any side effects) whereas AutoCloseable does not provide this feature. AutoCloseable was specially introduced to work with try-with-resources statements.


2 Answers

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.

like image 56
GhostCat Avatar answered Oct 26 '22 02:10

GhostCat


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.

like image 27
Lukas Eder Avatar answered Oct 26 '22 02:10

Lukas Eder