Question

Consider the following code:

public class ExchangeDataSimulatorStartup {

    public static ExecutorService executorService = Executors
            .newFixedThreadPool(Integer.parseInt(10);

public static void pullData() {


    boolean shutdown = false;

    while (!shutdown) {

        // create a list to hold the Future object associated with Callable
        List<Future<String>> futureList = new ArrayList<Future<String>>();

        while (stockSymbolsListItr.hasNext()) {
            PullStocksData pullStocksData = new PullStocksData(
                    stockSymbolsListItr.next());

            // submit Callable tasks to be executed by thread pool
            Future<String> future = executorService.submit(pullStocksData);

            // add Future to the list, we can get return value using Future
            futureList.add(future);
        }

    }
}

I need the executor service to shutdown whenever the application receives a shutdown signal. Otherwise the executor should keep running. So I saw the following implementation in another post which says I should add something like the following code in my main function:

try {

    // We will now start our ExchangeDataSimulator
        ExchangeDataSimulatorStartup.pullData();

 } catch (Exception ex) {

      // do some logging

 } finally {

   executorService.shutdown();

}

I believe the above code will work fine. Is it(shutting down the executor in finally block of the main method) the right way to do it? Are there any better approaches to this?

Was it helpful?

Solution

Usually I want to give tasks a chance to complete, but not for too long. See the method shown below:

/**
 * Shutdown the given executor service and wait for tasks to finish.
 * If tasks do not finish within the given time-out, the executor service is forcibly closed
 * (running tasks are interrupted) and tasks that never commenced execution are returned.  
 * @param es the executor service to shutdown
 * @param timeoutSeconds the maximum time in seconds to wait.
 * @return null on normal shutdown, else a list of tasks that never commenced execution
 */
public static List<Runnable> shutdown(ExecutorService es, int timeoutSeconds) {

    es.shutdown();
    if (timeoutSeconds > 0) {
        try {
            es.awaitTermination(timeoutSeconds, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            log.warn("Waiting for executor service tasks completion interrupted.", e);
        }
    }
    return (es.isTerminated() ? null : es.shutdownNow());
}

OTHER TIPS

Doing as you stated in the OP will have all the tasks wait for stopping. You can, however, force them to be interrupted if you use executorService.shutdownNow()

You may add the code to shutdown the ExecutorService as a shutdownhook that gets run when the application closes (naturally).

Runtime.getRuntime().addShutdownHook(new Thread() {
    public void run() {
        //shutdown executor service here

    }
});

With this piece of code it will be shutdown upon ending the application.

Note: This only gets called when the application is gracefully shutdown. If it gets terminated by a debugger or killed by process the above will not be executed. I'm actually not sure if it gets executed when the application crashes but I'll just assume it doesn't.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top