How to Properly Shutdown Java Executorservice

Best way to shutdown ExecutorService in Java

But I am worried what if write something wrong the code in callable
task f.get() takes forever and the program will halt forever and never
exit.

That's a bug. You need to make sure that doesn't happen.

With codes above, I can make sure threads are closed after 10 seconds

No, you can't. Even shutdownNow() doesn't actually guarantee that the executor threads are shut down (documentation):

There are no guarantees beyond best-effort attempts to stop processing
actively executing tasks. For example, typical implementations will
cancel via Thread.interrupt(), so any task that fails to respond to
interrupts may never terminate.

The ThreadPoolExecutor tries to "shut down now" by interrupting all worker threads. You need to make sure that your tasks handle interrupts correctly.

Once your tasks stop correctly, you can estimate how long a shutdown should take based on your application and the tasks you're shutting down. Then you can do a graceful shutdown:

  • Call shutdown()
  • Wait for an orderly shutdown for a reasonable amount of time using awaitShutdown()
  • If the executor is still running, call shutdownNow() and handle any outstanding tasks it returns.

How to properly shutdown executor services with Spring?

Are you aware that this:

ExecutorService service = Executors.newFixedThreadPool(4);

can be replaced with this:

<bean id="service" class="java.util.concurrent.Executors" 
factory-method="newFixedThreadPool" destroy-method="shutdown">
<constructor-arg value="4"/>
</bean>

The spring context then manages, more directly, the shutdown of your executor service--and it can be more easily reused.

shutting down ExecutorService in a spring boot Rest API

We currently have similar requirements, this is a difficult problem to solve as you want to use the right hammer if you will. There are very heavy weight solutions to orchestrating long running processes, for example SpringBatch.

Firstly though don't bother stop and starting the ExecutorService. The whole point of that class is to take the burden of Thread management off your hands, so you don't need to create and stop Threads yourself. So you don't need to manage the manager.

But be careful with your approach. Without using queues or another load balancing technique to smartly balance the long running processes across instances in your app. Or managing what happens when a Thread dies, you may get into a world of trouble. In general I would say nowadays it doesn't make much sense to interact directly with Threads or ThreadPools, and to use higher level solutions for this type of problem.



Related Topics



Leave a reply



Submit