How to run any task of a collection with ExecutorService in Java

The invokeAny method of the ExecutorService in Java executes a given list of tasks and returns the result that succeeds without throwing an exception. This method optionally takes a timeout parameter. Then, it returns the result if any tasks are completed within the timeout period.

Let’s consider we have a list of tasks that we wish to execute simultaneously. We are only interested in the result of any one task that completes successfully without throwing an exception.

For example, let’s consider searching for an element in a sorted array. Multiple algorithms can solve this problem. The invokeAny method gives us the one algorithm that searches the array and returns the result fastest.

Syntax

<T> T invokeAny(Collection<? extends Callable<T>> tasks)

Parameters

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

Return value

This method returns the result returned by one of the tasks.

Code

import java.util.Arrays;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
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 ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(3);
String taskResult = executorService.invokeAny(Arrays.asList(Main::algoOne, Main::algoTwo));
System.out.println("Result of best performing algo - " + taskResult);
executorService.shutdown();
}
}

Explanation

  • Lines 1 to 4: We import the relevant packages and classes.
  • Lines 8 to 14: We define a method called sleep(). This makes the current thread sleep for the specified number of milliseconds.
  • Lines 16 to 20: We define a method called algoOne(). This method prints Running algorithm one on the console, and makes the current thread sleep for one second. It then returns a string value.
  • Lines 22 to 26: We define a method called algoTwo(). This method prints Running algorithm two on the console, and makes the current thread sleep for one second. It then returns a string value.
  • Line 30: We define an executor service that consists of a fixed thread pool of three threads.
  • Line 32: We submit a list of tasks that execute algoOne() and algoTwo() at the same time as the invokeAny() method. The result of the task that is completed first, without any exception, is stored in a variable called taskResult.
  • Line 34: We print the taskResult.
  • Line 36: The executor service shuts down.

Note: We can run this program again without changing the code to see the different outcomes.

Free Resources