How to wait for thread pool to finish all tasks? - java

I am creating a thread pool executor and want it to finish all tasks before going forward:
for Example:
ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
while(...) {
taskExecutor.execute(new MyTask());
taskExecutor.execute(new MyTask());
taskExecutor.execute(new MyTask());
}
//...wait for completion somehow

there are multiple ways to do so:
but the popular one is using threadpool.shutdown():
public void awaitTerminationAfterShutdown(ExecutorService threadPool) {
threadPool.shutdown();
try {
if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) {
threadPool.shutdownNow();
}
} catch (InterruptedException ex) {
threadPool.shutdownNow();
Thread.currentThread().interrupt();
}
}

Different from the answer written, in scenarios the person will not usually know when the job finishes. As a rule of thumb, a more better approach is to have a callback from the running task.
You can do so like the following:
class MyTask implements Callable {...}//and do your task inside the "call" method
And then :
List<MyTask> allMyTasks // have all your tasks piled up
List<Future<TaskOutPut>> futures = taskExecutor.invokeAll(allMyTasks);
List<TaskOutPut> output = futures.map(future->future.get()).collect(Collectors.toList()); //this will make sure every future is completed

Related

What is the right way to use Java executor?

I am using Java executor in the following way, but not sure if every line is necessary and if this is the correct way to use it :
ExecutorService executor=Executors.newFixedThreadPool(30);
...
int N=200;
CountDownLatch doneSignal=new CountDownLatch(N);
for (int i=0;i<N;i++) executor.execute(new Test_Runner(doneSignal,...));
doneSignal.await();
executor.shutdown();
while (!executor.isTerminated()) { Thread.sleep(1000); }
// Blocks until all tasks have completed execution after a shutdown request
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
...
class Test_Runner implements Runnable
{
private CountDownLatch doneSignal;
Thread Test_Runner_Thread;
public Tes_Runner(CountDownLatch doneSignal,...)
{
this.doneSignal=doneSignal;
}
// Define some methods
public void run()
{
try
{
// do some work
}
catch (Exception e)
{
e.printStackTrace();
}
doneSignal.countDown();
}
public void start()
{
if (Test_Runner_Thread==null)
{
Test_Runner_Thread=new Thread(this);
Test_Runner_Thread.setPriority(Thread.NORM_PRIORITY);
Test_Runner_Thread.start();
}
}
public void stop() { if (Test_Runner_Thread!=null) Test_Runner_Thread=null; }
}
Looks correct to me. In the past I have followed the suggested implementation from the Java 7 JavaDoc for ExecutorService for stopping it. You can get it fromt he Java 7 Javadoc but I provide it below for convenience. Edit it to fit your needs, for example you might want to pass the number of seconds to wait. The good thing about using a CountDownLatch is that by the time it is done waiting you know the ExecutorService will terminate right away. Also, you might want to add a timeout to your latch's await if needed in future real world cases. Also, put your latch.countDOwn() in a try's finally block when using in real world application.
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
You can further simplify the code.
You can remove CountDownLatch.
Change Test_Runner to Callable task.
Create a ArrayList of Callable Tasks.
List<Test_Runner> callables = new ArrayList<Test_Runner>();
for (int i=0;i<N;i++) {
callables.add(new Test_Runner());
}
Use invokeAll() on executorService.
List<Future<String>> futures = executorService.invokeAll(callables);
From javadocs,
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException
Executes the given tasks, returning a list of Futures holding their status and results when all complete. Future.isDone() is true for each element of the returned list. Note that a completed task could have terminated either normally or by throwing an exception. The results of this method are undefined if the given collection is modified while this operation is in progress.
And you can shutdown executorService as proposed by Jose Martinez
Relate SE question : How to shutdown an ExecutorService?

Waiting for all the tasks to finish

I have a series of different "tasks" to be done using the same thread pool. I want to measure the time it takes to perform each task, but for that I need to wait for every task in the "task" (sorry for ambiguity) to finish.
When there's just one task I would normally do this:
ExecutorService e = Executors.newCachedThreadPool();
for (int i=0; i<100; ++i)
e.submit(target);
e.shutdown();
while (!e.isTerminated());
But since there will be several task submitted to the pool, I can't it down. All the methods that have something to do with waiting for the tasks to finish mention "after shutdown request". Well, what if I don't want to shut it down, but wait for all the threads to finish and then submit more tasks?
This is what I want to do:
ExecutorService e = Executors.newCachedThreadPool();
for (int i=0; i<100; ++i)
e.submit(target);
// wait for all targets to finish
for (int i=0; i<100; ++i)
e.submit(target); // submit different tasks
// wait... and so on
I thought of shutting the pool down and then "waking it up" again using prestartAllCoreThreads, but then I realized this was not an ExecutorService method but a ThreadPoolExecutor method. Could this be a solution? Shutting it down, waiting, and then activating the pool again? Seems a bit ugly to me.
I also thought that the most natural thing to do was to use a CyclicBarrier, but it seems too a specific way of doing this, while I think it would be the most logical thing to be able to use any ExecutorService for what I'm trying to do.
Is there any way I could stick to ExecutorServices and wait for all the tasks to finish?
Use CyclicBarrier for the work you need like so :
// the optionalRunnable can collect the data gathered by the tasks
CyclicBarrier b = new CyclicBarrier(numberOfTasks,optionalRunnable)
Task yourTaks = new Task(...., b);
// inside the run method call b.await() after the work is done;
executor.submit(yourTaks);
Optionally , you can also call await in the main thread and instantiate the barrier to numTasks + 1 . That way you are sure you're resubmitting tasks to the executor only after it's done processing the current batch
You can await the termination of that ExecutorService.
ExecutorService executor = Executors.newCachedThreadPool();
//do your stuff
try {
executor.shutdown();
executor.awaitTermination(5, TimeUnit.MINUTES);
} catch (InterruptedException e) {
//handle
}
Or use a CountDownLatch:
CountDownLatch latch = new CountDownLatch(totalNumberOfTasks);
ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
while(...) {
taskExecutor.execute(new MyTask());
}
try {
latch.await();
} catch (InterruptedException E) {
// handle
}
and within your task (enclose in try / finally)
latch.countDown();
You could create a TaskListener interface which you pass into each task. Each task notifies the TaskListener when they start and stop. Then you can create a TimingTaskListener implementation which maintains a ConcurrentMap of the durations which can be queried later.
public interface TaskListener {
void onStart(String taskId);
void onEnd(String taskId);
}
public class Task implements Runnable {
private TaskListener taskListener;
private String taskId;
public Task(String taskId, TaskListener taskListener) {
this.taskId = taskId;
this.listener = listener;
}
public void run() {
listner.onStart(taskId);
try {
doStuff();
} finally {
listener.onEnd(taskId);
}
}
}
// TODO: Implement TimingTaskListener to save durations to a ConcurrentMap
TimingTaskListener timingListener = new TimingTaskListener();
Runnable task1 = new Task("task1", timingListener);
Runnable task2 = new Task("task2", timingListener);
Future<?> f1 = e.submit(task1);
Future<?> f2 = e.submit(task2);
// futures block until the task is finished.
// You could also use a CountDownLatch to achieve the same
f1.get();
f2.get();
long time1 = timingListener.getDuration("task1");
long time2 = timingListener.getDuration("task2");

How to wait for all callables to finish executing before proceeding?

I have the following code hashed out:
public class MyCallable implements Callable<Long> {
#Override
public Long call() throws Exception {
// Do stuff...
}
}
public class MyController {
private ExecutorService executor = Executos.newCachedTreadPool();
public Long concurrentDoStuff() {
List<MyCallable> workers = makeWorkers();
List<Long> allResults = new ArrayList<Long>();
for(MyCallable worker : workers) {
Future<Long> workerResults = executor.submit(worker);
try {
allResults.add(workerResults.get());
} catch(InterruptedException ie) {
// Handle...
} catch(ExecutionException ee) {
// Handle...
}
}
// Question: how do I pause here and wait for all workers to finish?
}
}
After the for-loop, I want to wait for all workers to finish before proceeding any further. What's the best/safest/most-efficient way to do this? Thanks in advance!
Use a CountDownLatch.
Initialize it with the number of workers
Pass a reference to the latch in the worker constructor
When the worker is done, call countDown
Call await in the main thread and it will block until the workers are done.
This is a more general-purpose solution than using methods on the executor service.
You must shut the Executor down with shutDown and then wait until all jobs have been processed with awaitTermination.
You can call:
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE , TimeUnit.NANOSECONDS);
This will wait (almost) indefinitely for the tasks to complete.
There is a handy method.
ExecutorService.invokeAll(List<Callable> callables);
It will return List<Future> objects so that you can get the returned objects of all your individual call() methods.
You can get the instance of ExecutorService by calling Executors.new....()

Efficient way to wait for completion of Runnable tasks in ExecutorService

I have n-number of Runnable tasks (not Callable) that I am executing with ExecutorService.
I want to wait for all the tasks to complete.
I can't use invokeAll - because it works for collection of Callables.
I can't use shutdown()+awaitTermination, because awaittermination requires to provide a time out, but my tasks can take hours to complete.
I can use:
ExecutorService.shutdown();
while (!ExecutorService.isTerminated()) {}
But this loop will be always triggered.
What is suggested in such scenario?
ExecutorService.awaitTermination() returns a boolean which indicates if the executor terminated or the timeout has elapsed. You can ofcourse call it in a loop:
ExecutorService executor = ...;
executor.shutdown();
while (!executor.awaitTermination(24L, TimeUnit.HOURS)) {
System.out.println("Still waiting for the executor to finish");
}
System.out.println("Executor finished");
You can use ExecutorService.awaitTermination(Long.MAX_VALUE, TimeUnit.HOURS);
For known number of tasks the CountDownLatch is just perfect but there are cases, when you don't know how many tasks you will have, in that case I use Semaphore. For Example:
Semaphore s =new Semaphore(0);
while(..){
if (isLastTask){
taskExecutor.execute(new Task(s));
} else
taskExecutor.execute(new Task());
}
s.acquire(1);
class Task implement implements Runnable {
Semaphore s;
public Task(){
this(null);
}
public Task (Semaphore s){
this.s = s;
}
public void run(){
......
if ( s != null )
s.release();
}
}

How to stop all runnable thread in java executor class?

final ExecutorService executor = Executors.newFixedThreadPool(1);
final Future<?> future = executor.submit(myRunnable);
executor.shutdown();
if(executor.awaitTermination(10, TimeUnit.SECONDS)) {
System.out.println("task completed");
}else{
System.out.println("Executor is shutdown now");
}
//MyRunnable method is defined as task which I want to execute in a different thread.
Here is run method of executor class:
public void run() {
try {
Thread.sleep(20 * 1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}}
Here it is waiting for 20 second but when i run the code it throws an exception:
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
I am not able to close the concurrent thread ruining in Java Executor class. Here is my Code flow:
Created a new Thread with Java executor class to run some task i.e written in MyRunnable
executor wait for 10 second to complete the tasks.
If the task has completed then runnable thread also got terminated.
If the task is not completed within 10 second then executor class should terminate the thread.
Everything works fine except the termination of tasks in the last scenario. How should I do it?
The shutDown() method simply prevents additional tasks from being scheduled. Instead, you could call shutDownNow() and check for thread interruption in your Runnable.
// in your Runnable...
if (Thread.interrupted()) {
// Executor has probably asked us to stop
}
An example, based on your code, might be:
final ExecutorService executor = Executors.newFixedThreadPool(1);
executor.submit(new Runnable() {
public void run() {
try {
Thread.sleep(20 * 1000);
} catch (InterruptedException e) {
System.out.println("Interrupted, so exiting.");
}
}
});
if (executor.awaitTermination(10, TimeUnit.SECONDS)) {
System.out.println("task completed");
} else {
System.out.println("Forcing shutdown...");
executor.shutdownNow();
}
It is generally a bad idea to terminate a running thread from the outside, because you don't know the state the thread is currently in. It's possible that it needs to do some cleanups, and it won't be able to do that when you forcefully shut it down. That's why all methods of Thread which do that are marked as deprecated.
It's much better to use one of the many techniques which are available for interprocess communication to signal the procedure running in the thread itself that it has to abort its work and exit normally. One way to do this is to add an abort() method to your runnable, which raises a flag declared as volatile. The inner loop of your Runnable checks that flag and exits (in a controlled fashion) when that flag is raised.

Categories