Shutting down ExecutorService - java

According to documentation, when shutdown() is invoked, any tasks that were already submitted (I assume via submit() or execute) will be executed. When shutdownNow() is invoked, the executor will halt all tasks waiting to be processed, as well as attempt to stop actively executing tasks.
What I would like to clarify is the exact meaning of "waiting to be processed." For example, say I have an executor, and I call execute() on some number of Runnable objects (assume all of these objects effectively ignore interruptions). I know that if I now call shutdown, all of these objects will finish executing, regardless.
However, if I call shutdownNow at this point, will it have the same effect as calling shutdown? Or are some of the objects not executed? In other words, if I want an executor to exit as fast as possible, is my best option always to call shutdownNow(), even when the Runnables passed to the executor all effectively ignore interruptions?

Let's say you have this fabulous Runnable that is not interruptible for 10 seconds once it's started:
Runnable r = new Runnable() {
#Override
public void run() {
long endAt = System.currentTimeMillis() + 10000;
while (System.currentTimeMillis() < endAt);
}
};
And you have an executor with just 1 thread and you schedule the runnable 10 times:
ExecutorService executor = Executors.newFixedThreadPool(1);
for (int i = 0; i < 10; i++)
executor.execute(r);
And now you decide to call shutdown:
The executor continues for the full 10 x 10 seconds and everything scheduled will be executed. The tasks don't see that you're shutting down their executor. shutdown can be used if you want a "short lived" executor just for a few tasks. You can immediately call shutdown and it will get cleaned up later.
Alternatively shutdownNow():
Takes 10 seconds. The already running task is attempted to be interrupted, but that obviously has no effect so it continues to run. The other 9 tasks that were still waiting in the queue are "cancelled" and returned to you as List so you could do something with them, like schedule them later. Could also take 0 seconds if the first task is not yet started. You'd get all tasks back. The method is used whenever you want to abort an entire executor.

What I would like to clarify is the exact meaning of "waiting to be processed".
It means all tasks whose run() method has not yet been called (by the executor).
If I call shutdownNow at this point, will it have the same effect as calling shutdown?
No.
Or is it possible that some of the objects will not be executed?
That is correct.
In other words, if I want an executor to exit as fast as possible, is my best option always to call shutdownNow(), even when the Runnables passed to the executor all effectively ignore interruptions?
That is correct.
Better still, recode the Runnables to pay attention to interrupts ... or put a timeout on the shutdown ...

The API for shutdownNow method says that :
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.
source

Related

Best way to shutdown ExecutorService in Java

I am trying to write asynchronous programming in Java and I am using ExecutorService to create a pool backed by several threads to submit multiple callable tasks but I have few questions about how to shutdown the ExecutorService.
Here are my original codes:
ExecutorService executorService = Executors.newFixedThreadPool(10);
Future<String> f = executorService.submit(() -> {/*do something*/});
executorService.shutdown();
String result = f.get();
System.out.println(result);
This works good, and the executor shuts down after the threads are done. But I am worried what if write something wrong the code in callable task f.get() takes forever and the program will halt forever and never exit.
With the worry, here is my second try:
ExecutorService executorService = Executors.newFixedThreadPool(10);
Future<String> f = executorService.submit(() -> {/*do something*/});
executorService.shutdown();
if(!executorService.awaitTermination(10, TimeUnit.SECONDS)){
executorService.shutdownNow();
}
String result = f.get();
System.out.println(result);
With codes above, I can make sure threads are closed after 10 seconds. But actually the program is blocked for 10 seconds and thread may only use 5 seconds to be done.
My question is how to set the time to force to close threads in pool so that I do not need to explicitly use awaitTermination to block the program.
But I am worried what if write something wrong the code in callable
task f.get() takes forever and the program will halt forever and never
exit.
That's a bug. You need to make sure that doesn't happen.
With codes above, I can make sure threads are closed after 10 seconds
No, you can't. Even shutdownNow() doesn't actually guarantee that the executor threads are shut down (documentation):
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.
The ThreadPoolExecutor tries to "shut down now" by interrupting all worker threads. You need to make sure that your tasks handle interrupts correctly.
Once your tasks stop correctly, you can estimate how long a shutdown should take based on your application and the tasks you're shutting down. Then you can do a graceful shutdown:
Call shutdown()
Wait for an orderly shutdown for a reasonable amount of time using awaitShutdown()
If the executor is still running, call shutdownNow() and handle any outstanding tasks it returns.
I would like to add below points in addition to the above answers.
You can call the isDone() method of Future api before calling the get() method to verify that if the task is done as you are waiting for the task to be done via awaitTermination method of ExcuterService api.
But What I would suggest instead of using awaitTermination and shutdownNow you can use
get(long timeout, TimeUnit unit) [Waits if necessary for at most the
given time for the computation to complete, and then retrieves its
result, if available.]
of future API. It will throw TimeoutException if the timeout occurs, you may try to call shutdownNow.
you can also can check for shutdown status via isShutdown() method of ExecuterService API.
Your program should not blocked fro 10 second in your second version. It should wait for 10 seconds only if your threads does not terminate in 10 seconds. Your executor service will suspend the termination of all the threads in case of your threads does not complete in 10 seconds. From Java docs
/**
* Blocks until all tasks have completed execution after a shutdown
* request, or the timeout occurs, or the current thread is
* interrupted, whichever happens first.
*
* #param timeout the maximum time to wait
* #param unit the time unit of the timeout argument
* #return {#code true} if this executor terminated and
* {#code false} if the timeout elapsed before termination
* #throws InterruptedException if interrupted while waiting
*/

Java ExecutorService - What if awaitTermination() fails?

If I have the following code, which works fine:
ExecutorService service = Executors.newFixedThreadPool(100);
[....]
List<Future<SomeObject>> futures = service.invokeAll(callables);
for (Future f : futures) {
f.get();
}
// shutdown the service after all Callables are finished.
service.shutdown();
boolean serviceIsShutDown = service.awaitTermination(5, TimeUnit.SECONDS);
if (serviceIsShutDown) {
System.out.println("Service terminated normally. All ok.");
} else {
// What if it's not shutDown?
[...]
// this?
//service = null;
}
Question: What if the call
boolean serviceIsShutDown = service.awaitTermination(5, TimeUnit.SECONDS);
returns false because the timeout hits?
I guess the Threads in the ExecutorService will remain in state WAIT. What is the best solution to continue?
Setting the service to null and having the GarbageCollector remove it? But what happens with the related Threads? Will it ever be garbage collected as there are still references?
The code usually works, but just be curious. What to do if it returns false?
If awaitTermination() returns false in your example, you have an option to try calling shutdownNow(). This method will do its best to cancel all the tasks that are still being executed, but it guarantees nothing. Some poorly implemented tasks might have no cancellation policy and just run forever. In this case, the threads will never be terminated and the executor will never be garbage collected.
Such tasks will also prevent your program from graceful termination (if you don't mark your working threads as daemons).
For instance, if your task only contains an empty infinite loop, it won't be cancelled even if you call shutdownNow().
There also might be the case that a task has no proper cancellation policy, and runs too long (but not forever). For instance, it has a very-very long empty loop. You might fail to shutdown a pool that is being executed such task by means of shutdown()/shutdownNow(), but sooner or later it will finish its work and the thread will be terminated along with the executor.
If you want to "force" the termination of your ExecutorService just use:
shutdownNow()
look here for description:

Program does not terminate immediately when all ExecutorService tasks are done

I put a bunch of runnable objects into an ExecutorService:
// simplified content of main method
ExecutorService threadPool = Executors.newCachedThreadPool();
for(int i = 0; i < workerCount; i++) {
threadPool.execute(new Worker());
}
I would expect my program/process to stop immediately after all workers are done. But according to my log, it takes another 20-30 seconds until that happens. The workers do not allocate any resources, in fact, they do nothing at the moment.
Don't get me wrong, this is not a crucial problem for me, I'm just trying to understand what is happening and I'm wondering if this is normal behavior.
Executors.newCachedThreadPool() uses Executors.defaultThreadFactory() for its ThreadFactory. defaultThreadFactory's javadocs say that "each new thread is created as a non-daemon thread" (emphasis added). So, the threads created for the newCachedThreadPool are non-daemon. That means that they'll prevent the JVM from exiting naturally (by "naturally" I mean that you can still call System.exit(1) or kill the program to cause the JVM to halt).
The reason the app finishes at all is that each thread created within the newCachedThreadPool times out and closes itself after some time of inactivity. When the last one of them closes itself, if your application doesn't have any non-daemon threads left, it'll quit.
You can (and should) close the ExecutorService down manually via shutdown or shutdownNow.
See also the JavaDoc for Thread, which talks about daemon-ness.
I would expect my program/process to stop immediately after all workers are done. But according to my log, it takes another 20-30 seconds until that happens. The workers do not allocate any resources, in fact, they do nothing at the moment.
The problem is that you are not shutting down your ExecutorService. After you submit all of the jobs to the service, you should shutdown the service or the JVM will not terminate unless all of the threads in it are daemon threads. If you do not shutdown the thread-pool then any threads associated with the ExecutorService, again if not daemon, will stop the JVM from finishing. If you've submitted any tasks to a cached thread pool then you will have to wait for the threads to timeout and get reaped before the JVM will finish.
ExecutorService threadPool = Executors.newCachedThreadPool();
for(int i = 0; i < workerCount; i++) {
threadPool.execute(new Worker());
}
// you _must_ do this after submitting all of your workers
threadPool.shutdown();
Starting the threads as daemon is most likely not what you want to do because your application may stop before the tasks have completed and all of the tasks will be terminated immediately at that time. I just did a quick audit and of the 178 times we use ExecutorService classes in our production code, only 2 of them were started as daemon threads. The rest are properly shutdown.
If you need to force an ExecutorService to stop when the application is exiting then using shutdownNow() with proper handling of the thread interrupt flags is in order.
Basically on an ExecutorService you call shutdown() and then awaitTermination():
ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
while(...) {
taskExecutor.execute(new MyTask());
}
taskExecutor.shutdown();
try {
taskExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
...
}
From the javadoc for Executors.newCachedThreadPool():
Threads that have not been used for sixty seconds are terminated and removed from the cache.
It is usually a good idea to call shutdown() on an ExecutorService if you know that no new tasks will be submitted to it. Then all tasks in the queue will complete, but the service will then shut down immediately.
(Alternately, if you don't care if all the tasks complete - for example, if they are handling background calculations that are irrelevant once your main UI is gone - then you can create a ThreadFactory that sets all the threads in that pool to be daemon.)
For multi threading of ExecutorService
Solution is
threadPool.shutdown();
It is due to combination keepAliveTime=60L, timeunit=TimeUnit.SECONDS and corePoolSize=0*: when thread completes task, it does not terminate immediately, it may** wait during keepAliveTime for a new task.
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
*if core poolSize != 0 see method allowCoreThreadTimeOut() of ThreadPoolExecutor
**waiting depends on combination of current quantity of running threads in pool, corePoolSize and maximumPoolSize

What is the exit strategy for Executors.newSingleThreadExecutor()

I'm new to java concurrency so this may be a question already answered many time over or too obvious that I maybe missing something.
I am running as task like so:
Executors.newSingleThreadExecutor().execute(task)
My question is when its comes to end of executing the run method of task why does it not exit or why is the thread still alive? My understanding was once a threads run() completes the thread is no more and ceases to exist, right?
newSingleThreadExecutor returns an ExecutorService which uses a single thread - it can still execute multiple tasks. It doesn't exit because you may want to supply more tasks.
You can use:
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(task);
service.shutdown();
to shut it down after the task has executed.
the thread remains alive because its lifecycle is not tied to that of the tasks assigned to the executor; take a look at:
javadoc for Executors.newSingleThreadExecutor
you'll find that internally, the returned ExecutorService uses a single thread to sequentially run as many tasks as you assign to it, potentially instantiating a new thread if one of your tasks kills the original one.

Does ThreadPoolExecutor spawns a new thread if a current thread sleeps

This question is a followup on this one.
Essentially what I am doing is declaring a ThreadPoolExecutor with just one thread. I am overriding the beforeExecute() method to put a sleep so that each of my tasks are executed with some delay among themselves. This is basically to give away the CPU to other threads since my thread is kind of thrashing.
So the expected behavior is:
For each new task in the ThreadPoolExecutor, it calls the before execute function before executing the task and hence it sleeps for say 20s before it executes the task.
However this is what I see:
For each new task submitted:
It executes the task
Calls the beforeExecute method
sleeps for say 20s
RE-EXECUTE the task!
The order of 1. & 2. is not the same all the time.
Here are my questions:
It is appearing that a new thread comes in after/during sleeping and goes ahead and executes my task right away while the actual thread is sleeping.
So does the ThreadPoolExecutor spawn a new thread as soon as an existing thread sleeps [thinking that the thread is terminated]??
I tried to put the keepAliveTime > sleeptime ..so that in case the above assertion is true .. it atleast waits for more than sleep time to spawn a new thread ...[hoping in the mean time the sleeping thread would be awake and the ThreadPoolExecutor would dump the idea of spawning a new thread
Even if it does spawn a new thread and execute my task right away, why would the task be re-executed after the sleeping thread wakes up !! Shouldn't the task be taken out of task Queue before that ??
Am I missing something here ? Any other way to debug this scenario ?
=> An alternative method I was thinking to do the desired task [and not solve the peoblem] was to wrap the runnable with one more runnable and sleep the outer runnable before calling the inner one.
I think what you're looking for is a ScheduledExecutorService
From what I understand of your question, scheduleAtFixedRate(...) should do the deal:
scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
Creates and executes a periodic action
that becomes enabled first after the
given initial delay, and subsequently
with the given period; that is
executions will commence after
initialDelay then initialDelay+period,
then initialDelay + 2 * period, and so
on.
No, that is not how it works. The ThreadPoolExecutor knows it has a worker thread, even if that worker is RUNNABLE, WAITING, BLOCKED, or any other state.
The task is removed from the BlockingQueue long before the beforeExecute method is invoked.
You can look at the code for the API yourself and determine what it is doing. Every Java JDK installation includes a "src.zip" file which contains the entire Java Library. If yu haven't already, you can attach this source in eclipse and then while debugging in eclipse diving into a library method will show you source instead of just the class file.

Categories

Resources