Search code examples
javaexecutorserviceshutdown-hookcompletion-service

Java add shutdown hook inside method


In my code I'm using CompletionService and ExecutorService in order to start a bunch of Thread to execute some task (that can take a lot of time). So I have a method that creates the ExecutorService and the CompletionService, then starts submitting threads and then take the results. I would like to add a shutdown hook in order to gracefully shutdown the executor (I know that probably I should handle releasing resources instead of executor shutdown but in my case each thread has its own resources so shutting down them gracefully can be a good soulution I suppose).

For this reason I write the following code

public Class myClass{
...
private CompletionService<ClusterJobs> completion;
final long SHUTDOWN_TIME = TimeUnit.SECONDS.toSeconds(10);

...
public Message executeCommand(Message request){

final ExecutorService executor = Executors.newFixedThreadPool(30);

completion = new ExecutorCompletionService<ClusterJobs>(executor);

....//submit and take results

Runtime.getRuntime().addShutdownHook(new Thread(){
            @Override
            public void run() {
                logger.debug("Shutting down executor");

                try {
                    if (!executor.awaitTermination(SHUTDOWN_TIME, TimeUnit.SECONDS)) {
                        logger.debug("Executor still not terminate after waiting time...");
                        List<Runnable> notExecuted= executor.shutdownNow();
                        logger.debug("List of dropped task has size " + droppedTasks.size());
                    }
                }catch(InterruptedException e){
                    logger.error("",e);
                }
            }
        });

}
}

Do you think that this is a reasonable solution or it's unsafe to register and unregister shutdown hook using local classes?

Thanks in advance

Regards


Solution

  • From Design of the Shutdown Hooks API:

    Simple shutdown hooks can often be written as anonymous inner classes, as in this example:

    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() { database.close(); }
    });
    

    This idiom is fine as long as you'll never need to cancel the hook, in which case you'd need to save a reference to the hook when you create it.