Two Laptop Bag*
The moose likes Threads and Synchronization and the fly likes Why do we need awaitTermination? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Why do we need awaitTermination?" Watch "Why do we need awaitTermination?" New topic
Author

Why do we need awaitTermination?

Swerrgy Smith
Ranch Hand

Joined: Mar 26, 2010
Posts: 88
Hi all,

We usually use this method and shutdown() method in the same time:



Perhaps I don't understand clearly the method awaitTermination() of the class ExecutorService.
But I think shutdown() is enough because shutdown() does not "kill" the submitted tasks. It also allows the executor service to wait until these tasks terminate.

Can anyone explain me why do we need awaitTermination()?

Thank you very much.
Chan Ag
Bartender

Joined: Sep 06, 2012
Posts: 1000
    
  16
But I think shutdown() is enough because shutdown() does not "kill" the submitted tasks. It also allows the executor service to wait until these tasks terminate.


This is precisely the reason why sometimes the shutdown() may not be enough. shutdown() just ensures that no new tasks are accepted. The submitted tasks and currently running tasks are allowed to continue.
Sometimes this is not what you'd want. You'd probably want to wait for sometime before you issue another shutdownNow(), in which case an attempt would be made to interrupt the currently executing tasks.
Among many other uses awaitTermination( <params> ) may have, one of the use is that it allows you to specify a time duration for waiting before you issue a shutdownNow().

And you may want to keep checking at regular intervals, if termination is complete. It also throws an InterruptedException if the thread that issued it is interrupted in which case you can reissue a shutdownNow in the catch block.

Chan.
Swerrgy Smith
Ranch Hand

Joined: Mar 26, 2010
Posts: 88
Hi,

I think I understand the problem. According to the description of 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."

Does this method block the current thread (i.e. the thread that use the executor) and NOT the executor itself?
If so, it's like join() method: blocking the current thread until another thread finishes.

Thanks


Chan Ag wrote:
But I think shutdown() is enough because shutdown() does not "kill" the submitted tasks. It also allows the executor service to wait until these tasks terminate.


This is precisely the reason why sometimes the shutdown() may not be enough. shutdown() just ensures that no new tasks are accepted. The submitted tasks and currently running tasks are allowed to continue.
Sometimes this is not what you'd want. You'd probably want to wait for sometime before you issue another shutdownNow(), in which case an attempt would be made to interrupt the currently executing tasks.
Among many other uses awaitTermination( <params> ) may have, one of the use is that it allows you to specify a time duration for waiting before you issue a shutdownNow().

And you may want to keep checking at regular intervals, if termination is complete. It also throws an InterruptedException if the thread that issued it is interrupted in which case you can reissue a shutdownNow in the catch block.

Chan.
Chan Ag
Bartender

Joined: Sep 06, 2012
Posts: 1000
    
  16
Does this method block the current thread (i.e. the thread that use the executor) and NOT the executor itself?


Yes, it blocks the current thread, i.e the thread that issued the awaitNotification(<args>) awaitTermination(<args>) instruction. You can actually test it by creating a set of Runnable tasks, creating another runnable and in the run method of this runnable you could create a ThreadPoolExecutor and submit/execute the first set of runnable tasks you created. This will give you a thread other than main within which you can monitor the tasks submitted to the executor. There are other ways to do this as well, but this is simple enough for us to understand how awaitNotification awaitTermination works.

You may need executor monitoring for various purposes. For instance there could be an admin expecting some notification after a certain interval has passed after you issued the shutDown(). It might be possible that it is really critical because of scheduling of additional dependent tasks or something, or may be somebody needs to take an action. Just guessing here - reasons could be anything.

Here is a rough example that I used for my understanding.



The above class creates a runnable task that can be interrupted because it invokes Thread.sleep() periodically.

The following class is a runnable that creates a TPE within its run method and then executes 20 runnable tasks via the TPE.



Here is the output.
Main started at 1377973699355
Thread Thread-0 started at 1377973699355
Main ended at 1377973699355
Thread Thread-0 is going to create 20 tasks at 1377973699365

Thread pool-1-thread-1 started at 1377973699365
Thread pool-1-thread-2 started at 1377973699365
pool-1-thread-2 printed hello user at 1377973699365
pool-1-thread-1 printed hello user at 1377973699365
Thread pool-1-thread-4 started at 1377973699365
pool-1-thread-4 printed hello user at 1377973699365
Thread pool-1-thread-5 started at 1377973699365
pool-1-thread-5 printed hello user at 1377973699365
Thread pool-1-thread-3 started at 1377973699365
pool-1-thread-3 printed hello user at 1377973699365
Thread pool-1-thread-7 started at 1377973699365
pool-1-thread-7 printed hello user at 1377973699365
Thread pool-1-thread-8 started at 1377973699365
pool-1-thread-8 printed hello user at 1377973699365
Thread pool-1-thread-9 started at 1377973699365
pool-1-thread-9 printed hello user at 1377973699365
Thread Thread-0 is done creating tasks at 1377973699365
Thread pool-1-thread-6 started at 1377973699365
pool-1-thread-6 printed hello user at 1377973699365
Thread Thread-0 invoked shutdown at 1377973699365
Thread pool-1-thread-10 started at 1377973699365
pool-1-thread-10 printed hello user at 1377973699365
Thread Thread-0 was INTERRUPTED AT 1377973699365
Thread Thread-0 invoked shutdownNow at 1377973699365

Thread pool-1-thread-8 was interrupted at 1377973699365
Thread pool-1-thread-7 was interrupted at 1377973699365
Thread pool-1-thread-9 was interrupted at 1377973699365
Thread pool-1-thread-2 was interrupted at 1377973699365

pool-1-thread-2 printed hello user at 1377973699365
Thread pool-1-thread-4 was interrupted at 1377973699365
pool-1-thread-4 printed hello user at 1377973699365
Thread pool-1-thread-6 was interrupted at 1377973699365
pool-1-thread-6 printed hello user at 1377973699365
Thread Thread-0 ended at 1377973699365
Thread pool-1-thread-1 was interrupted at 1377973699365
pool-1-thread-1 printed hello user at 1377973699365
pool-1-thread-9 printed hello user at 1377973699365
Thread pool-1-thread-10 was interrupted at 1377973699365
pool-1-thread-10 printed hello user at 1377973699365
pool-1-thread-7 printed hello user at 1377973699365
pool-1-thread-8 printed hello user at 1377973699365
Thread pool-1-thread-3 was interrupted at 1377973699365
Thread pool-1-thread-5 was interrupted at 1377973699365
pool-1-thread-5 printed hello user at 1377973699365
pool-1-thread-3 printed hello user at 1377973699365
pool-1-thread-8 printed hello user at 1377973700365
pool-1-thread-2 printed hello user at 1377973700365
pool-1-thread-10 printed hello user at 1377973700365
pool-1-thread-3 printed hello user at 1377973700365
pool-1-thread-1 printed hello user at 1377973700365
pool-1-thread-6 printed hello user at 1377973700365
pool-1-thread-7 printed hello user at 1377973700365
pool-1-thread-4 printed hello user at 1377973700365
pool-1-thread-9 printed hello user at 1377973700365
pool-1-thread-5 printed hello user at 1377973700365
pool-1-thread-1 printed hello user at 1377973701365
pool-1-thread-8 printed hello user at 1377973701365
pool-1-thread-7 printed hello user at 1377973701365
pool-1-thread-6 printed hello user at 1377973701365
pool-1-thread-3 printed hello user at 1377973701365
pool-1-thread-4 printed hello user at 1377973701365
pool-1-thread-5 printed hello user at 1377973701365
pool-1-thread-9 printed hello user at 1377973701365
pool-1-thread-2 printed hello user at 1377973701365
pool-1-thread-10 printed hello user at 1377973701365
pool-1-thread-8 printed hello user at 1377973702365
pool-1-thread-2 printed hello user at 1377973702365
pool-1-thread-1 printed hello user at 1377973702365
pool-1-thread-6 printed hello user at 1377973702365
pool-1-thread-7 printed hello user at 1377973702365
pool-1-thread-3 printed hello user at 1377973702365
pool-1-thread-10 printed hello user at 1377973702365
pool-1-thread-4 printed hello user at 1377973702365
pool-1-thread-9 printed hello user at 1377973702365
pool-1-thread-5 printed hello user at 1377973702365
Thread pool-1-thread-2 ended at 1377973703365
Thread pool-1-thread-1 ended at 1377973703365
Thread pool-1-thread-7 ended at 1377973703365
Thread pool-1-thread-4 ended at 1377973703365
Thread pool-1-thread-9 ended at 1377973703365
Thread pool-1-thread-5 ended at 1377973703365
Thread pool-1-thread-3 ended at 1377973703365
Thread pool-1-thread-6 ended at 1377973703365
Thread pool-1-thread-8 ended at 1377973703365
Thread pool-1-thread-10 ended at 1377973703365
BUILD SUCCESSFUL (total time: 5 seconds)


Hope it helps.

If so, it's like join() method: blocking the current thread until another thread finishes.


I'd say, in a way, yes. But again, a thread and a TPE are different things. This one waits for the termination of all threads in the TPE unless a TimeUnit is specified.
I think ( almost assuming/guessing here ) technically it should be wrong to say it's like the join method. And also we don't know the implementation details of the join() method and the awaitTermination() method.
They may/may not be similar. Who knows what else is happening at the implementation level, unless someone who knows about it comments on it.

So I'd leave that for someone else to comment on. I have no idea.

Chan.

Edit : References to awaitNotification deleted. There is no such method. I meant awaitTermination. Chan, 9th October, 2013.

 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Why do we need awaitTermination?
 
Similar Threads
ThreadPoolExecutor restart
How to correctly use a fixed size thread pool?
ServletContextListener (contextDestroyed) with Threads
Shutdown Threadpoolexecutor when queue is empty[SOLVED]
Thread sync issue