0

The Java doc for shutdown() says:

shutdown

void shutdown()

Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.Invocation has no additional effect if already shut down. This method does not wait for previously submitted tasks to complete execution. Use awaitTermination to do that.

Aren't the two statements contradictory? (...previously submitted tasks are executed Vs does not wait for previously submitted tasks to complete execution) ?

I tried out a sample program with shutdown(). And it does wait for previously submitted tasks to complete unlike shutdownNow()!

Why the below code returns I have shutdown true when it is supposed to wait for the factorial task to complete?

public class RunnableMain {

    public static void main(String[] args) {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        RunnableFactorialTask runnableFactorialTask = new RunnableFactorialTask(5);
        executor.submit(runnableFactorialTask);
        executor.shutdown();
        System.out.println(" I have shutdown.."+executor.isShutdown());
    }
}

class RunnableFactorialTask implements Runnable {

    private int num = 0;

    public RunnableFactorialTask(int num) {
        this.num = num;
    }

    @Override
    public void run() {
        int factorial = 1;
        try {
            Thread.currentThread().sleep(6000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        for (int i = 2; i <= num; i++) {
            factorial *= i;
        }
        System.out.println("factorial of :" + num + " =" + factorial);
    }
}
raikumardipak
  • 1,461
  • 2
  • 29
  • 49
  • The "does not wait for previously submitted tasks to complete execution" simply means the method call returns immediately. If it were to wait then calling `shutdown()` would only return once all tasks are complete. The difference between `shutdown()` and `shutdownNow()` is that the latter will attempt to cancel any currently running tasks and will not run still-queued tasks, whereas the former will do neither and simply let the tasks run to completion then terminate. – Slaw Dec 12 '19 at 07:24
  • Do you mean `ExecutorService#shutdown()`? – dan1st Dec 12 '19 at 07:48
  • @Slaw "let the tasks run to completion then terminate" is the confusion.(?) If the control comes back immediately on calling shutdown or shutdownNow then where is the letting the tasks run to completion. It seems these tasks are independent threads while executor service itself is an independent thread. So while executor service is shutdown immediately the tasks it had scheduled are left on their own to complete? – raikumardipak Dec 12 '19 at 08:16
  • 1
    Typically, an `ExecutorService` manages a pool of threads responsible for executing tasks. When a task is submitted it is placed in a queue until one of those pool threads can take the task and execute it. When you shutdown an `ExecutorService` it stops accepting _new_ tasks, but the already-submitted tasks will still be processed. After shutdown, once a pool thread finishes its task and there's no more left in the queue the thread is allowed to die. Once all pool threads are dead the `ExecutorService` is terminated. – Slaw Dec 12 '19 at 08:42
  • @Slaw Can you help me to understand the o/p of the above code? The isshutdown() returns true even though as explained by you the threadpool is still awaiting tasks to complete. (If I understood correctly..) – raikumardipak Dec 12 '19 at 08:43
  • As I've explained, calling shutdown allows already-submitted tasks to complete. That doesn't mean the `ExecutorService` isn't shutdown, all that means is that it's not _terminated_. The sequence is: _created → running → shutdown → terminated_. – Slaw Dec 12 '19 at 08:45
  • Executor Service lifecycle : created ---> running -----> shutdown ------> terminated Thanks @Slaw – raikumardipak Feb 27 '20 at 14:27

1 Answers1

5

The calls to shutdownNow() or shutdown() are not blocking. That is what is referred to in the docs. So if you call shutdown() or shutdownNow(), you get control back immediately, not only after everything has gracefully shut down. If you want to wait for all executors/threads to terminate after the call to shutdown[Now](), you have to call awaitTermination(...), which will block until everything is cleaned up. This is probably what you want. Also see answers to a similar question here: Difference between shutdown and shutdownNow of Executor Service

AndreasT
  • 9,417
  • 11
  • 46
  • 60