Wait for completion of all tasks in ExecutorService

suggest change

Let’s have a look at various options to wait for completion of tasks submitted to Executor

  1. ExecutorService invokeAll()
Executes the given tasks, returning a list of Futures holding their status and results when everything is completed.

Example:

import java.util.concurrent.*;
import java.util.*;

public class InvokeAllDemo{
    public InvokeAllDemo(){
        System.out.println("creating service");
        ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        
        List<MyCallable> futureList = new ArrayList<MyCallable>();
        for (int i = 0; i < 10; i++){
            MyCallable myCallable = new MyCallable((long)i);
            futureList.add(myCallable);
        }
        System.out.println("Start");
        try{
            List<Future<Long>> futures = service.invokeAll(futureList);  
        } catch(Exception err){
            err.printStackTrace();
        }
        System.out.println("Completed");
        service.shutdown();
    }
    public static void main(String args[]){
        InvokeAllDemo demo = new InvokeAllDemo();
    }
    class MyCallable implements Callable<Long>{
        Long id = 0L;
        public MyCallable(Long val){
            this.id = val;
        }
        public Long call(){
            // Add your business logic
            return id;
        }
    }
}
  1. CountDownLatch
>  A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.

> A **CountDownLatch** is initialized with a given count. The await methods block until the current count reaches zero due to invocations of the `countDown()` method, after which all waiting threads are released and any subsequent invocations of await return immediately. This is a one-shot phenomenon -- the count cannot be reset. If you need a version that resets the count, consider using a **CyclicBarrier**.
  1. ForkJoinPool or newWorkStealingPool() in Executors
  2. Iterate through all Future objects created after submitting to ExecutorService
  3. Recommended way of shutdown from oracle documentation page of ExecutorService:
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();
    }

`shutdown():`  Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.

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.

In above example, if your tasks are taking more time to complete, you can change if condition to while condition

Replace

if (!pool.awaitTermination(60, TimeUnit.SECONDS))

with

while(!pool.awaitTermination(60, TimeUnit.SECONDS)) {
  Thread.sleep(60000);
}

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:


Executor, ExecutorService and Thread pools:
* Wait for completion of all tasks in ExecutorService

Table Of Contents
8 Arrays
10 Maps
11 Strings
23 Executor, ExecutorService and Thread pools
25 JAXB
29 Enums
32 Audio
41 Scanner
63 Logging
75 Lists
78 Sets
89 JAX-WS
96 XJC
98 Process
106 Modules
114 Applets
122 JNDI
139 JavaBean
141 Literals
144 Packages
150 JMX
153 JShell
159 Sockets
167 Enum Map
175 Hashtable
177 SortedMap