Giovanni Botta Giovanni Botta - 1 year ago 173
Java Question

How to properly shutdown executor services with Spring?

I have a command line application that uses a Spring-managed bean that's composed of a java

created with:

ExecutorService service = Executors.newFixedThreadPool(4);

Now, I want my service to shutdown when my application shuts down, so I made my bean implement the
interface and have a destroy method such as:

public void destroy(){

Then I might be tempted to do something like register a shutdown hook on the Spring context. However I found out (the hard way, i.e., in a pre-production release) that this doesn't work: the shutdown hook doesn't get called before the
method is called, causing a classic catch 22 problem (it does get called on interruption, i.e., if I hit Ctrl-C while the application is running). This escaped my unit tests because for some reason it seems to work fine from within JUnit, which is still puzzling me: what does JUnit do differently?

The solution I found so far is to explicitly call
right before I exit my main function. I was wondering if there was a better solution to this and what are the best practices for having flexible thread pools managed by Spring. Also what if my bean is not directly managed by Spring but is created by a bean managed by Spring? Should I just cascade the calls to
? Wouldn't this be very error prone?

I appreciate any comments, suggestions, further reading, RTFMs, magic recipes.


Answer Source

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"/>

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

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download