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 printsRunning algorithm oneon 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 printsRunning algorithm twoon 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()andalgoTwo()at the same time as theinvokeAny()method. The result of the task that is completed first, without any exception, is stored in a variable calledtaskResult. - 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.