How to run all tasks of collection with ExecutorService in Java

The invokeAll() method of the ExecutorService in Java executes a given list of tasks, and returns a list of Futures that hold the results of all the tasks.

Let’s consider we have a list of tasks that we wish to execute simultaneously. We are interested in the results of all the tasks.

For example, let’s consider searching for an element in a sorted array. Multiple algorithms can solve this problem. The invokeAll() method gives us the results of all algorithms that searches the array.

Syntax

<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)

Parameters

  • Collection<? extends Callable<T>> tasks: It is the list of tasks to be executed.

Return value

This method returns a list of futures representing the tasks, in the same sequential order as produced by the iterator for the given task list.

Code

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Main {
private static void sleep(int millis){
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
private static String algoOne(){
System.out.println("Running algorithm one");
sleep(1000);
return "algoOne Result";
}
private static String algoTwo(){
System.out.println("Running algorithm two");
sleep(1000);
return "algoTwo Result";
}
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(3);
List<Future<String>> taskFutures = executorService.invokeAll(Arrays.asList(Main::algoOne, Main::algoTwo));
taskFutures.forEach(res -> {
try {
System.out.println("Result - " + res.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
});
executorService.shutdown();
}
}

Explanation

  • Lines 1 to 6: We import the relevant packages and classes.
  • Lines 10 to 16: We define a method called sleep(). This makes the current thread sleep for the specified number of milliseconds.
  • Lines 18 to 22: We define a method called algoOne(). This method prints Running algorithm one on the console and makes the current thread sleep for one second, and then returns a string value.
  • Lines 24 to 28: We define a method called algoTwo(). This method prints Running algorithm two on the console and makes the current thread sleep for one seconds, and then returns a string value.
  • Line 32: We define an executor service that consists of a fixed thread pool of three threads.
  • Line 34: We submit a list of tasks that execute the algoOne() and algoTwo() at the same time as the invokeAll method. We get a list futures called taskFutures.
  • Lines 36 to 42: We loop through each future in taskFutures. We then retrieve the result of each task using the get() call method, and print it to the console.
  • Line 44: The executor service shuts down.

Free Resources