Question

Please, help to understand ExecutorService#awaitTermination(timeout) behaviour.

I'm observing situation when I have in my code:

private void shutdownAndAwaitTermination(ExecutorService threadPool){
    threadPool.shutdown(); 
    try {
        if (!threadPool.awaitTermination(threadPoolTimeout, TimeUnit.HOURS)){
            threadPool.shutdownNow(); 
            if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) {
                logger.warn("Pool did not terminate");
            }
        }
    }
    catch (InterruptedException ie)     {
        threadPool.shutdownNow();
        Thread.currentThread().interrupt();
    }
}

Does the tasks in pool complete in this case before any other calls after shutdownAndAwaitTermination() in same thread ?

Looking into what is happening on production, I believe that the answer is no, but I just want to understand how to make sure that any code placed after call to shutdownAndAwaitTermination() will happen after last task in pool completes.

Thanks.

Was it helpful?

Solution

No, tasks could definitely complete after you return from your shutdownAndAwaitTermination() method, because you don't actually await termination. If the waiting thread is interrupted, or if it takes too long, you stop waiting, even though tasks may still be running.

Even if you call shutdownNow(), your tasks may not respond to interruption (and in general, ExecutorService isn't guaranteed to use interruption). So tasks may still be running.

If you want to ensure task completion happens-before returning from this method, you have to keep trying until awaitTermination() returns true, in spite of interrupts, etc. That would be a bad design, so it would be better if your tasks returned their results via a Future instead of producing side-effects non-atomically. That way, tasks that complete successfully can be acted upon, while tasks that do not complete can be ignored.

OTHER TIPS

from http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html:

List<Runnable> shutdownNow
Attempts to stop all actively executing tasks, halts the processing of waiting tasks,
and returns a list of the tasks that were awaiting execution.   
This method does not wait for actively executing tasks to terminate.
Use awaitTermination to do that.

There is no way to accurately stop running thread, so you have to wait for already running tasks to finish.

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