64

What is the difference between

ExecutorService eService = Executors.newFixedThreadPool(2);
eService.execute(new TestThread6());
eService.execute(new TestThread6());
eService.execute(new TestThread6());
eService.awaitTermination(1, TimeUnit.NANOSECONDS);
eService.shutdown();

and

eService.shutdown();
eService.awaitTermination(1, TimeUnit.NANOSECONDS);

I don't really understand shutdown(). This method does not wait for previously submitted tasks to complete execution. Does it mean shutdown() may terminate the tasks which have been submitted, but not completed? I tried some examples, they do not prove it, please give me an example.

Ravindra babu
  • 45,953
  • 8
  • 231
  • 206
王奕然
  • 3,541
  • 4
  • 37
  • 59
  • 1
    Have a look at : https://stackoverflow.com/questions/36644043/how-to-properly-shutdown-java-executorservice/36644320#36644320 – Ravindra babu Aug 26 '17 at 17:48

9 Answers9

76

You should call shutdown first. Otherwise, you might be waiting for a very long time, since awaitTermination doesn't actually shut down your executor.

If you wanted to wait for tasks to complete, rather than wait for the executor to shut down, then you should use invokeAll.

Chris Jester-Young
  • 213,251
  • 44
  • 377
  • 423
  • thanks,but why waiting for a very long time?could you give me some example to explain? – 王奕然 Aug 25 '13 at 02:24
  • 5
    @user2245634 `awaitTermination` doesn't actually shut down your executor first. So unless another thread shuts down the executor, `awaitTermination` will just sit there until the timeout runs out. Obviously, in your example, you were waiting only 1 nanosecond before timing out, which was why you didn't observe the "very long time". – Chris Jester-Young Aug 25 '13 at 02:25
  • 1
    thanks,i understand,and in shutdown() api:This method does not wait for previously submitted tasks to complete execution. it means maybe shutdown() may terminate the task which have submited,but not complete?but i try some examples not prove it – 王奕然 Aug 25 '13 at 02:39
  • @user2245634 Correct, any incomplete tasks will be cancelled (their threads will be sent interrupts). If your tasks don't check for interrupts, however, then of course cancellation won't work. – Chris Jester-Young Aug 25 '13 at 02:49
  • please look this code public class TestThread9 implements Runnable{ @Override public void run() { if (Thread.interrupted()) { System.out.println("interrupted"); return; } System.out.println("a"); } public static void main(String[] args) throws InterruptedException { ExecutorService eService = Executors.newFixedThreadPool(2); eService.execute(new TestThread9()); eService.execute(new TestThread9()); eService.shutdown(); } }in this example,i only call shutdown(),not call awaitTermination ,and i check interrupt but not "interrupted" was print – 王奕然 Aug 25 '13 at 03:11
  • @user2245634 Your task finished before it was interrupted. Try doing something like: `while (!Thread.interrupted()) {System.out.println("loop"); Thread.sleep(1000);}`. You will see results. – Chris Jester-Young Aug 25 '13 at 03:26
  • i try use your code,and call shutdown(),but never terminate,and print "loop" forever:public class TestThread9 implements Runnable{ @Override public void run() { while (!Thread.interrupted()) {System.out.println("loop"); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }} } public static void main(String[] args) throws InterruptedException { ExecutorService eService = Executors.newFixedThreadPool(2); eService.execute(new TestThread9()); eService.execute(new TestThread9()); eService.shutdown(); } – 王奕然 Aug 25 '13 at 04:55
  • 24
    Note that `shutdown()` does not interrupt already executing tasks. From javadoc : "Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted." If you want interruption you should call `shutDownNow()`. – bowmore Aug 25 '13 at 08:32
  • @user2245634 What bowmore said. (Just said that to highlight your name, so you get notified.) – Chris Jester-Young Aug 25 '13 at 12:18
  • shutdown terminates all the threads and awaitTermination after shutdown is redundant. – Amrish Pandey Jul 01 '15 at 14:54
  • 2
    @AmrishPandey No, that's not what the documentation says. See S.D.'s answer. What you describe is what shutdownNow does. – Yngvar Kristiansen Jul 29 '16 at 08:26
  • The ideal construct is shutdown() ; followed by if(!awaitTermination) -> shutdownNow() – Achow Feb 19 '21 at 04:52
55

Reading the documentation always helps:

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. These tasks are drained (removed) from the task queue upon return from this method.

This method does not wait for actively executing tasks to terminate. Use awaitTermination to do that.

There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. This implementation cancels tasks via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate

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.

awaitTermination:

Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first.

S.D.
  • 28,804
  • 3
  • 80
  • 126
  • 19
    I do not understand the documentation for shutdown. It first says "previously submitted tasks are executed" and then it says "this method does not wait for previously submitted tasks to complete execution." So, will my tasks run to completion or not? – jmrah Feb 12 '17 at 01:10
  • 29
    @jrahhali It means method call returns immediately. I.e. the thread that calls `shutdown` does not blocks. – S.D. Feb 13 '17 at 07:55
  • 13
    Ahh, does not block. That makes sense now. They should've used that word instead of wait. Thanks. – jmrah Feb 13 '17 at 13:48
  • One slight modification on @S.D.'s answer. Where they say that "`shutdown` does not wait for previously submitted tasks to complete execution", I believe they mean that the current thread does _not_ **block** until the previously submitted tasks complete execution. – Jason Nov 29 '21 at 21:26
20

shutdown means the executor service takes no more incoming tasks.

awaitTermination is invoked after a shutdown request.

You need to first shut down the service and then block and wait for threads to finish.

If you want to see all threads finish running and insist on using awaiTermination, you need to set the timeout parameter to be big enough. So you could do:

eService.shutdown();
if (!eService.awaitTermination(60000, TimeUnit.SECONDS))
    System.err.println("Threads didn't finish in 60000 seconds!");
}

Alternatively, you could do:

eService.shutdown();
while (!eService.isTerminated()) {

}

This way you are able to ensure all threads are finished running unless they are interrupted unexpectedly.

Terry Li
  • 16,014
  • 29
  • 84
  • 132
10

Main Difference

shutdown()-

1. Doesn't block the calling a thread i.e. the thread who called the shutdown().
2. Excecutor doesn't accept any new task after calling shutdown().

awaitTermination() -

1. Blocks the calling thread. (as join() method do)

Point of Confusion:- If shutdown() does not kill the previously submitted tasks, why do we need awaitTermination()?

awaitTermination means waiting for the tasks to be completed/terminated, right? shutdown() is doing the same- waiting for any task which is already submitted along with the running tasks to continue till completed/terminated, then why another method awaitTermination(..)? Below is the explanation:

Suppose you can wait for 10 min only to complete all the task that are submitted and after that want to call shutdownNow()(---you already know what it do) then use awaitTermination(long timeout, TimeUnit unit) after calling shutdown().

Notice the method arguments in awaitTermination(long timeout, TimeUnit unit). This timeout is the key here.

If there is no time restriction, shutdown() is OK. No need of awaitTermination().

Dexter
  • 3,476
  • 3
  • 42
  • 53
Ashwani Tiwari
  • 1,367
  • 17
  • 28
  • 1
    IMHO, instead of awaitTermination(long timeout, TimeUnit unit), shutdown(long timeout, TimeUnit unit) would have been less confusing. Then would not have to call shutdown() first, then awaitTermination(..). Can any one enlighten on the logic behind a separate method instead of overloading shutdown() ? – Dexter Sep 10 '20 at 15:54
  • What if awaitTermination exit the block and there are still tasks running? How do you make sure all the task in the pool are terminated/killed (if timeout is reached) before proceeding? – Marco Dufal Nov 16 '21 at 15:08
  • As I mentioned in answer, we just call awaitTermination before calling shutdownNow(), giving some time to task in pool to execute or complete. If they not completed in the given time , you will shutdown the executor – Ashwani Tiwari Nov 16 '21 at 15:45
8

The best implementation:

executor.shutdown();
try {
    if (!executor.awaitTermination(3500, TimeUnit.MILLISECONDS)) {
        executor.shutdownNow();
    }                   
} catch (InterruptedException e) {              
    executor.shutdownNow();
}
        
informatik01
  • 15,636
  • 10
  • 72
  • 102
Xavy Guzman
  • 81
  • 1
  • 2
3

After we start the first task ThreadPoolExecutor will start a Thread that will not end even after the task is finished. At least it's true for a fixed thread pool. This is why we need to call shutdown. After shutdown ThreadPoolExecutor will reject any new task but will wait for running tasks to finish and then allow the Threads to end. This is why we need awaitTermination after shutdwon.

Evgeniy Dorofeev
  • 129,181
  • 28
  • 195
  • 266
2
executorService.execute(runnableTask);  

//executorService.shutdown(); //it will make the executorService stop accepting new tasks
//executorService.shutdownNow(); //tires to destroy the executorService immediately, but it doesn't guarantee that all the running threads will be destroyed at the same time. This method returns list of tasks which are waiting to be processed.
//List<Runnable> notExecutedTasks = executorService.shutdownNow(); //this method returns list of tasks which are waiting to be processed.developer decide what to do with theses tasks?

//one good way to shutdown the executorService is use both of these methods combined with the awaitTermination
executorService.shutdown();
try{
    if(!executorService.awaitTermination(1000, TimeUnit.MICROSECONDS)) {
        executorService.shutdownNow();
    }
}catch (InterruptedException e){
    e.printStackTrace();
}
HansHirse
  • 16,433
  • 10
  • 30
  • 56
0

From Java8 ThreadPool awaitTermination method:

    try {
        for (;;) {
            if (runStateAtLeast(ctl.get(), TERMINATED))
                return true;
            if (nanos <= 0)
                return false;
            nanos = termination.awaitNanos(nanos);
        }
    } finally {
        mainLock.unlock();
    }

It will first check run state of thread pool. And if the thread pool is not shut down(which set run state to terminated), awaitTermination method will not return until timeout. This explains why await a long time if you await first then shutdown.

Gawain
  • 832
  • 5
  • 14
-2

You need to call shutdownNow() method after the awaitTermination() method call happened. Then only you can find out the actual usage of awaitTermination() method.

Cà phê đen
  • 1,817
  • 2
  • 19
  • 19
user3094331
  • 441
  • 4
  • 18