Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shutdown ExecutorService gracefully in webapp?

Tags:

In my webapp, I created a service that is using an ExecutorService with fixed size ThreadPool. I reuse the same ExecutorService during the whole application lifetime.

private static ExecutorService pool = Executors.newFixedThreadPool(8); 

All is running in Tomcat which gives me the following error while shuting down:

appears to have started a thread named [pool-1-thread-1] but has failed to stop it. This is very likely to create a memory leak. 

I do realize I need to shutdown the ExecutorService before shuting tomcat down. Soms SO thread already speak about this but I could not find a clean way to handle this.

Should I use a ShutdownHook as suggested @Tim-bender in Graceful shutdown of threads and executor ? Or should I use a CachedThreadPool instead?

like image 271
Olivier.Roger Avatar asked Oct 10 '12 08:10

Olivier.Roger


People also ask

How do I shut down ExecutorService gracefully?

When using an Executor, we can shut it down by calling the shutdown() or shutdownNow() methods. Although, it won't wait until all threads stop executing. Waiting for existing threads to complete their execution can be achieved by using the awaitTermination() method.

Should ExecutorService be shutdown?

Upon termination, an executor has no tasks actively executing, no tasks awaiting execution, and no new tasks can be submitted. An unused ExecutorService should be shut down to allow reclamation of its resources.

Can I use ExecutorService after shutdown?

As stated in the documentation, you cannot reuse an ExecutorService that has been shut down.

Is ExecutorService blocked?

It is not blocking, it is just that in Java as long is there are non-daemon threads the application is not closing: class Test{ public static void main(String[] args){ ExecutorService exec = new Executors. newCachedThreadPool(); exec.


2 Answers

Shutdown hook is not a good approach in Tomcat because:

  • it will close the pool too late (on shutdown), Tomcat will already warn you about not closed resources

  • you actually want to shutdown that pool when application is undeployed so that redeployment works (otherwise each application will create new pool and they will all be closed only on complete shutdown)

  • shutting down the thread pool might take some time (see below), shutdown hook should be as fast as possible

Much better place is ServletContextListener.contextDestroyed(). Remember you have to both shutdownNow() the pool (to cancel running and reject new tasks) and awaitTermination() to wait for already running tasks to finish and all threads to stop.

like image 135
Tomasz Nurkiewicz Avatar answered Sep 23 '22 05:09

Tomasz Nurkiewicz


In addition to what Tomasz suggested you can also use CachedThreadPool

Threads that have not been used for sixty seconds are terminated and removed from the cache. Thus, a pool that remains idle for long enough will not consume any resources

So a very good solution would be use CachedThreadPool and shutdown it in ServletContextListener.contextDestroyed().

like image 45
Amit Deshpande Avatar answered Sep 22 '22 05:09

Amit Deshpande