Difference between shutdown and shutdownNow of Executor Service
In summary, you can think of it that way:
shutdown()
will just tell the executor service that it can't accept new tasks, but the already submitted tasks continue to runshutdownNow()
will do the same AND will try to cancel the already submitted tasks by interrupting the relevant threads. Note that if your tasks ignore the interruption,shutdownNow
will behave exactly the same way asshutdown
.
You can try the example below and replace shutdown
by shutdownNow
to better understand the different paths of execution:
- with
shutdown
, the output isStill waiting after 100ms: calling System.exit(0)...
because the running task is not interrupted and continues to run. - with
shutdownNow
, the output isinterrupted
andExiting normally...
because the running task is interrupted, catches the interruption and then stops what it is doing (breaks the while loop). - with
shutdownNow
, if you comment out the lines within the while loop, you will getStill waiting after 100ms: calling System.exit(0)...
because the interruption is not handled by the running task any longer.
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.submit(new Runnable() {
@Override
public void run() {
while (true) {
if (Thread.currentThread().isInterrupted()) {
System.out.println("interrupted");
break;
}
}
}
});
executor.shutdown();
if (!executor.awaitTermination(100, TimeUnit.MICROSECONDS)) {
System.out.println("Still waiting after 100ms: calling System.exit(0)...");
System.exit(0);
}
System.out.println("Exiting normally...");
}
From the javadocs:
void shutdown
Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.
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.
There are no guarantees beyond best-effort attempts to stop processing actively executing tasks.
For example, typical implementations will cancel via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate.
Returns: list of tasks that never commenced execution
shutdown()
:
To terminate the threads inside the ExecutorService you call its shutdown()
method. The ExecutorService will not shut down immediately, but it will no longer accept new tasks, and once all threads have finished current tasks, the ExecutorService shuts down. All tasks submitted to the ExecutorService before shutdown() is called, are executed.
shutdownNow()
:
If you want to shut down the ExecutorService immediately, you can call the shutdownNow()
method. This will attempt to stop all executing tasks right away, and skips all submitted but non-processed tasks. There are no guarantees given about the executing tasks. Perhaps they stop, perhaps the execute until the end. It is a best effort attempt.