Cleaning up thread submitted using ExecutorService - java

My code is as follows:
public Future<String> getFuture() {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<String> future = executorService.submit(() -> {
//do something
return "test string";
});
executorService.shutDown(); // is this correct?
return future;
}
I am calling this service from other class to get the future:
Future<String> future = getFuture();
String result = future.get();
future.cancel(true); // will this assure that there wont be any thread leak?
Now out of executorService.shutDown() and future.cancel(true) which will assure that there wont be thread leaks?
Note that after calling future.cancel(true) when I check currently running threads in the result of Thread.getAllStackTraces() I can still find the thread where future executed.

You are asking the wrong question!
There is no point in creating a service within a method to then throw it away right there.
Creating that service instance doesn't come for free. The whole idea of this abstraction is to ensure to make efficient usage of infrastructure elements!
In other words: step back and rework your design; so that this service becomes a field of some class for example! And yes, that might turn out to be complicated. But most likely, spending time in that corner will pay out much more long term - compared to continuing the approach shown in your question.

It is a bad idea to create an executor then throw it away in each method call.
Now out of executorService.shutDown() and future.cancel(true) which will assure that there wont be thread leaks?
none of them.
executorService.shutdown() will just keep running the current tasks and reject new submitted tasks.
future.cancel(true) will interrupt the corresponding task if it is currently running (but it is your responsability to check if the task was interrupted and finish the execution of the task as soon as possible)
Note that after calling future.cancel(true) when I check currently running threads in the result of Thread.getAllStackTraces() I can still find the thread where future executed.
as I mentioned before, future.cancel(true) doesn't stop the thread. it only sends an interruption.

Related

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:

Does awaitTermination in ExecutorService "happens-before" any code executed after it?

Please, help to understand ExecutorService#awaitTermination(timeout) behaviour.
I'm observing situation when I have in my code:
private void shutdownAndAwaitTermination(ExecutorService threadPool){
threadPool.shutdown();
try {
if (!threadPool.awaitTermination(threadPoolTimeout, TimeUnit.HOURS)){
threadPool.shutdownNow();
if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) {
logger.warn("Pool did not terminate");
}
}
}
catch (InterruptedException ie) {
threadPool.shutdownNow();
Thread.currentThread().interrupt();
}
}
Does the tasks in pool complete in this case before any other calls after shutdownAndAwaitTermination() in same thread ?
Looking into what is happening on production, I believe that the answer is no, but I just want to understand how to make sure that any code placed after call to shutdownAndAwaitTermination() will happen after last task in pool completes.
Thanks.
No, tasks could definitely complete after you return from your shutdownAndAwaitTermination() method, because you don't actually await termination. If the waiting thread is interrupted, or if it takes too long, you stop waiting, even though tasks may still be running.
Even if you call shutdownNow(), your tasks may not respond to interruption (and in general, ExecutorService isn't guaranteed to use interruption). So tasks may still be running.
If you want to ensure task completion happens-before returning from this method, you have to keep trying until awaitTermination() returns true, in spite of interrupts, etc. That would be a bad design, so it would be better if your tasks returned their results via a Future instead of producing side-effects non-atomically. That way, tasks that complete successfully can be acted upon, while tasks that do not complete can be ignored.
from http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html:
List<Runnable> 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.
This method does not wait for actively executing tasks to terminate.
Use awaitTermination to do that.
There is no way to accurately stop running thread, so you have to wait for already running tasks to finish.

Stop a Runnable submitted to ExecutorService

I've implemented subscription in my Java app. When new subscriber added, the application creates new task (class which implements Runnable to be run in the separate thread) and it is added to the ExecutorService like:
public void Subscribe()
{
es_.execute(new Subscriber(this, queueName, handler));
}
//...
private ExecutorService es_;
Application may register as many subscribers as you want. Now I want implement something like Unsubscribe so every subscriber has an ability to stop the message flow. Here I need a way to stop one of the tasks running in the ExecutorService. But I don't know how I can do this.
The ExecutorService.shutdown() and its variations are not for me: they terminates all the tasks, I want just terminate one of them. I'm searching for a solution. As simple as possible. Thanks.
You can use ExecutorService#submit instead of execute and use the returned Future object to try and cancel the task using Future#cancel
Example (Assuming Subscriber is a Runnable):
Future<?> future = es_.submit(new Subscriber(this, queueName, handler));
...
future.cancel(true); // true to interrupt if running
Important note from the comments:
If your task doesn't honour interrupts and it has already started, it will run to completion.
Instead of using ExecutorService.execute(Runnable) try using Future<?> submit(Runnable). This method will submit the Runnable into the pool for execution and it will return a Future object. By doing this you will have references to all subscriber threads.
In order to stop particular thread just use futureObj.cancel(true). This will interrupt the running thread, throwing an InterruptedException. The subscriber thread should be coded such way it will stop processing in the case of this exception (for example Thread.sleep(millis) with wrapper try / catch block for the whole method).
You cand find more information on the official API:
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html

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.

How to wait for all tasks in an ThreadPoolExecutor to finish without shutting down the Executor?

I can't use shutdown() and awaitTermination() because it is possible new tasks will be added to the ThreadPoolExecutor while it is waiting.
So I'm looking for a way to wait until the ThreadPoolExecutor has emptied it's queue and finished all of it's tasks without stopping new tasks from being added before that point.
If it makes any difference, this is for Android.
Thanks
Update: Many weeks later after revisiting this, I discovered that a modified CountDownLatch worked better for me in this case. I'll keep the answer marked because it applies more to what I asked.
If you are interested in knowing when a certain task completes, or a certain batch of tasks, you may use ExecutorService.submit(Runnable). Invoking this method returns a Future object which may be placed into a Collection which your main thread will then iterate over calling Future.get() for each one. This will cause your main thread to halt execution until the ExecutorService has processed all of the Runnable tasks.
Collection<Future<?>> futures = new LinkedList<Future<?>>();
futures.add(executorService.submit(myRunnable));
for (Future<?> future:futures) {
future.get();
}
My Scenario is a web crawler to fetch some information from a web site then processing them. A ThreadPoolExecutor is used to speed up the process because many pages can be loaded in the time. So new tasks will be created in the existing task because the crawler will follow hyperlinks in each page. The problem is the same: the main thread do not know when all the tasks are completed and it can start to process the result. I use a simple way to determine this. It is not very elegant but works in my case:
while (executor.getTaskCount()!=executor.getCompletedTaskCount()){
System.err.println("count="+executor.getTaskCount()+","+executor.getCompletedTaskCount());
Thread.sleep(5000);
}
executor.shutdown();
executor.awaitTermination(60, TimeUnit.SECONDS);
Maybe you are looking for a CompletionService to manage batches of task, see also this answer.
(This is an attempt to reproduce Thilo's earlier, deleted answer with my own adjustments.)
I think you may need to clarify your question since there is an implicit infinite condition... at some point you have to decide to shut down your executor, and at that point it won't accept any more tasks. Your question seems to imply that you want to wait until you know that no further tasks will be submitted, which you can only know in your own application code.
The following answer will allow you to smoothly transition to a new TPE (for whatever reason), completing all the currently-submitted tasks, and not rejecting new tasks to the new TPE. It might answer your question. #Thilo's might also.
Assuming you have defined somewhere a visible TPE in use as such:
AtomicReference<ThreadPoolExecutor> publiclyAvailableTPE = ...;
You can then write the TPE swap routine as such. It could also be written using a synchronized method, but I think this is simpler:
void rotateTPE()
{
ThreadPoolExecutor newTPE = createNewTPE();
// atomic swap with publicly-visible TPE
ThreadPoolExecutor oldTPE = publiclyAvailableTPE.getAndSet(newTPE);
oldTPE.shutdown();
// and if you want this method to block awaiting completion of old tasks in
// the previously visible TPE
oldTPE.awaitTermination();
}
Alternatively, if you really no kidding want to kill the thread pool, then your submitter side will need to cope with rejected tasks at some point, and you could use null for the new TPE:
void killTPE()
{
ThreadPoolExecutor oldTPE = publiclyAvailableTPE.getAndSet(null);
oldTPE.shutdown();
// and if you want this method to block awaiting completion of old tasks in
// the previously visible TPE
oldTPE.awaitTermination();
}
Which could cause upstream problems, the caller would need to know what to do with a null.
You could also swap out with a dummy TPE that simply rejected every new execution, but that's equivalent to what happens if you call shutdown() on the TPE.
If you don't want to use shutdown, follow below approaches:
Iterate through all Future tasks from submit on ExecutorService and check the status with blocking call get() on Future object as suggested by Tim Bender
Use one of
Using invokeAll on ExecutorService
Using CountDownLatch
Using ForkJoinPool or newWorkStealingPool of Executors(since java 8)
invokeAll() on executor service also achieves the same purpose of CountDownLatch
Related SE question:
How to wait for a number of threads to complete?
You could call the waitTillDone() on Runner class:
Runner runner = Runner.runner(10);
runner.runIn(2, SECONDS, runnable);
runner.run(runnable); // each of this runnables could submit more tasks
runner.waitTillDone(); // blocks until all tasks are finished (or failed)
// and now reuse it
runner.runIn(500, MILLISECONDS, callable);
runner.waitTillDone();
runner.shutdown();
To use it add this gradle/maven dependency to your project: 'com.github.matejtymes:javafixes:1.0'
For more details look here: https://github.com/MatejTymes/JavaFixes or here: http://matejtymes.blogspot.com/2016/04/executor-that-notifies-you-when-task.html
Try using queue size and active tasks count as shown below
while (executor.getThreadPoolExecutor().getActiveCount() != 0 || !executor.getThreadPoolExecutor().getQueue().isEmpty()){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}

Categories

Resources