How to Wait for All Tasks in an Threadpoolexecutor to Finish Without Shutting Down the Executor

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

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

How to wait for all tasks within a ThreadPoolExecutor to finish within a timeout and without shutting the Executor down?

This would be an outline of a solution:

  1. calculate the deadline for task completion: deadline = currentTimeMillis() + timeout;
  2. loop through all the futures, calling future.get(timeLeft, MILLISECONDS), each time adjusting timeLeft = deadline - currentTimeMillis();
  3. if the deadline is reached, then break out of this loop and go into the cancellation loop.

final long deadline = System.currentTimeMillis() + timeout;
for (Future<?> f : futures) {
final long timeLeft = deadline - System.currentTimeMillis();
if (timeLeft <= 0) break;
try {
f.get(timeLeft, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
break;
}
}

for (Future<?> f : futures) {
if (!future.isDone()) {
future.cancel(true);
}
}

How do I wait for ThreadPoolExecutor.map to finish

Executor.map will run jobs in parallel and wait futures to finish, collect results and return a generator. It has done the wait for you. If you set a timeout, it will wait until timeout and throw exception in generator.

map(func, *iterables, timeout=None, chunksize=1)

  • the iterables are collected immediately rather than lazily;
  • func is executed asynchronously and several calls to func may be made concurrently.

To get a list of futures and do the wait manually, you can use:

myfuturelist = [pool.submit(_exec, x) for x in range(5)]

Executor.submit will return a future object, call result on future will explicitly wait for it to finish:

myfutrelist[0].result() # wait the 1st future to finish and return the result

How to wait for all threads to finish, using ExecutorService?

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) {
...
}

Shutdown a ThreadPoolExecutor before all tasks are finished

If you can switch to Python 3.9, it's got this feature built-in to the shutdown method:

If cancel_futures is True, this method will cancel all pending futures that the executor has not started running. Any futures that are completed or running won’t be cancelled, regardless of the value of cancel_futures.

Java: Wait in a loop until tasks of ThreadPoolExecutor are done before continuing

You should look into CyclicBarrier or a CountDownLatch. Both of these allow you to prevent threads starting unless other threads have signaled that they're done. The difference between them is that CyclicBarrier is reusable, i.e. can be used multiple times, while CountDownLatch is one-shot, you cannot reset the count.

Paraphrasing from the Javadocs:

A CountDownLatch is a synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.

A CyclicBarrier is a synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. CyclicBarriers are useful in programs involving a fixed sized party of threads that must occasionally wait for each other. The barrier is called cyclic because it can be re-used after the waiting threads are released.

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/CyclicBarrier.html

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/CountDownLatch.html

How to wait for a ThreadPoolExecutor to finish

You should loop on awaitTermination

ExecutorService threads;
// ...
// Tell threads to finish off.
threads.shutdown();
// Wait for everything to finish.
while (!threads.awaitTermination(10, TimeUnit.SECONDS)) {
log.info("Awaiting completion of threads.");
}


Related Topics



Leave a reply



Submit