87

I want to know the basic difference between shutdown() and shutdownNow() for shutting down the Executor Service?

As far as I understood:

shutdown() should be used for graceful shutdown which means all tasks that were running and queued for processing but not started should be allowed to complete

shutdownNow() does an abrupt shut down meaning that some unfinished tasks are cancelled and unstarted tasks are also cancelled. Is there anything else which is implicit/explicit that I am missing?

P.S: I found another question on How to shutdown an executor service related to this but not exactly what I want to know.

catch23
  • 17,519
  • 42
  • 144
  • 217
Geek
  • 26,489
  • 43
  • 149
  • 227
  • 6
    Did you read the API documentation of the two methods? It explains exactly what each method does. – Jesper Jul 17 '12 at 10:03
  • That's how I have it as well... I usually call shutdown() and if the tasks do not finish in a specific time, I call shutdownNow() to force the shutdown. Has worked fine so far. – Jaco Van Niekerk Jul 17 '12 at 10:04
  • 2
    @Jesper from api documentation only I gathered the information . I want know if there is something else that I am missing . – Geek Jul 17 '12 at 10:05
  • 2
    @downvoter why the down vote ? Does it lack research effort or what ? Any constructive comments on the reason for downvote ? – Geek Jul 17 '12 at 10:07
  • 1
    Yes, it shows a lack of research. You basically ask something which is answered in the javadoc. – JB Nizet Jul 17 '12 at 11:10
  • 1
    I do not agree: read the shutdown doc which I found contradictory. PS: up vote from me – Adrian Jun 17 '18 at 08:48

3 Answers3

154

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 run
  • shutdownNow() 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 as shutdown.

You can try the example below and replace shutdown by shutdownNow to better understand the different paths of execution:

  • with shutdown, the output is Still waiting after 100ms: calling System.exit(0)... because the running task is not interrupted and continues to run.
  • with shutdownNow, the output is interrupted and Exiting 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 get Still 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...");
}
assylias
  • 321,522
  • 82
  • 660
  • 783
  • Ok, so that means shutDownNow() method will jsut interrupt the executing thread and set the interupted flag to true, but it is up to task implementer to do something based on that flag, framework or shutDownNow() method is not going to force you to stop the thread. is that what you meant? – AKS Aug 23 '13 at 23:45
  • 1
    Please answer me on this: does shutDownNow() interrupts all threads that are still running their tasks ? and the common thing between shutDown() and shutDownNow() is canceling pending tasks that aren't assigned to any thread yet? – android developer Jan 19 '14 at 09:08
  • 5
    Yes / No: shutdown does not cancel waiting tasks, it only prevents new tasks from being submitted. But a task that has already been submitted will run as soon as a thread is available. – assylias Jan 19 '14 at 09:50
  • 9
    To add to the confusion, in the doc API it says that shutdown() `This method does not wait for previously submitted tasks to complete execution. Use awaitTermination to do that.` It says it **does not wait** which is contrary to this answer. – supertonsky Jan 21 '16 at 08:06
  • 9
    @supertonsky "*it does not wait*", in that context, means that calling shutdown returns immediately, without blocking (`awaitTermination` does block). But it lets the tasks that have been previously submitted finish what they are doing. – assylias Jan 21 '16 at 08:16
  • 1
    Thanks for clarifying that out. They could have worded it a little different. – supertonsky Jan 21 '16 at 09:31
  • 1
    Why do we need the `if` condition? Shouldn't the `shutdownNow` interruption force an exception to be thrown? Or is it because the thread gets all the CPU due to the infinite loop? (and that's why it cannot be enforced to interrupt). – Maroun Apr 26 '16 at 12:04
  • @MarounMaroun which if condition (there are two of them)? – assylias Apr 26 '16 at 12:24
  • @assylias The one inside the infinite while loop. – Maroun Apr 26 '16 at 12:25
  • 1
    @MarounMaroun you can test with and without it - with the condition the task will exit as soon as the thread is interrupted, without the condition the infinite loop will keep running, preventing the executor from shutting down. – assylias Apr 26 '16 at 12:27
  • @assylias Exactly, I'm actually asking *why* we need the condition. Wouldn't the thread be interrupted and throws an exception without this condition? – Maroun Apr 26 '16 at 12:28
  • 5
    @MarounMaroun when a thread is interrupted, its interrupt flag is set to true. But that's it, the interruption doesn't stop the thread (and it doesn't throw an interruption either). So you need to check the interrupt flag regularly and exit gracefully when you catch it (typically by exiting, like in the example, or by throwing an InterruptedException). In the example, when the condition is removed, you need to force the program termination with System.exit(0) otherwise it will keep running indefinitely. – assylias Apr 26 '16 at 12:33
  • It seems that `shutdownNow` can interrupt a thread in the middle of execution. I would like to wait for the execution to complete but I don't want to wait for `delayed` tasks. I see that, if using a `ScheduledThreadPoolExecutor` I can call `setExecuteExistingDelayedTasksAfterShutdownPolicy`, but how can I do this if I used `Executors.newSingleThreadScheduledExecutor` and only have a `ScheduledExecutorService` Object? – theyuv Jul 01 '19 at 16:52
  • This is a bit different, you should ask a separate question. – assylias Jul 02 '19 at 14:45
  • @assylias If I want to immediately terminate the ExecutorService and all submitted tasks (including the actively executing tasks), is System.exit() a reasonable/good approach? When System.exit() terminates the current running JVM, it also terminates all threads, right? – Peng Mar 05 '20 at 21:25
  • I believe it does but you could ask a separate question if you can't find a definite answer. – assylias Mar 08 '20 at 21:45
9
  • 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.

Ahmed MANSOUR
  • 2,369
  • 2
  • 27
  • 35
2

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

Ernest Sadykov
  • 831
  • 8
  • 28
fmucar
  • 14,361
  • 2
  • 45
  • 50