shutdown and awaitTermination which first call have any difference?

JavaMultithreadingExecutorservice

Java Problem Overview


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.

Java Solutions


Solution 1 - Java

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.

Solution 2 - Java

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.

Solution 3 - Java

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.

Solution 4 - Java

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().

Solution 5 - Java

The best implementation:

executor.shutdown();
try {
    if (!executor.awaitTermination(3500, TimeUnit.MILLISECONDS)) {
	    executor.shutdownNow();
	}			    	
} catch (InterruptedException e) {				
    executor.shutdownNow();
}
		

Solution 6 - Java

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.

Solution 7 - Java

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();
}

Solution 8 - Java

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.

Solution 9 - Java

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Question王奕然View Question on Stackoverflow
Solution 1 - JavaChris Jester-YoungView Answer on Stackoverflow
Solution 2 - JavaS.D.View Answer on Stackoverflow
Solution 3 - JavaTerry LiView Answer on Stackoverflow
Solution 4 - JavaAshwani TiwariView Answer on Stackoverflow
Solution 5 - JavaXavy GuzmanView Answer on Stackoverflow
Solution 6 - JavaEvgeniy DorofeevView Answer on Stackoverflow
Solution 7 - Javauser11656780View Answer on Stackoverflow
Solution 8 - JavaGawainView Answer on Stackoverflow
Solution 9 - Javauser3094331View Answer on Stackoverflow