ExecutorService invokeAll()

Learn to run multiple Callable tasks with ExecutorService.invokeAll(tasks) API and processing all the results returned from tasks in form of Future class instances in this ExecutorService Callable example.

1. ExecutorService invokeAll() API

invokeAll() method executes the given list of Callable tasks, returning a list of Future objects holding their status and results when all complete.

It is overloaded method and is in two forms. Second method takes extra parameters denoting the timeout. The TimeUnit class is an enumeration with the following constants: DAYS, HOURS, MICROSECONDS, MILLISECONDS, MINUTES, NANOSECONDS, and SECONDS.

/**
* @param  - tasks - the collection of tasks
* @return - a list of Futures representing the tasks, in the same
*           sequential order as produced by the iterator for the
*           given task list.
*/
<T> List<Future<T>>	invokeAll(Collection<? extends Callable<T>> tasks)

/**
* @param - tasks - the collection of tasks
* @param - timeout - the maximum time to wait
* @param - unit - the time unit of the timeout argument
* @return - a list of Futures representing the tasks, in the same
*           sequential order as produced by the iterator for the
*           given task list.
*/
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)

An important point to note that the first object in the list of Future objects will be the object that controls the first task in the list of Callable objects, the second object the second task, and so on.

2. ExecutorService invokeAll() Example

In this example, we are creating a demo task which does nothing but to print some statements. This is to not introduce any complexity and focus on core concept.

class Task implements Callable<Result> 
{
	private final String name;

	public Task(String name) {
		this.name = name;
	}

	@Override
	public Result call() throws Exception 
	{
		System.out.printf("%s: Staring\n", this.name);

		try {
			long duration = (long) (Math.random() * 10);
			System.out.printf("%s: Waiting %d seconds for results.\n", this.name, duration);
			TimeUnit.SECONDS.sleep(duration);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		return new Result(this.name, LocalDateTime.now().toString());
	}
}

Similarly, we are collecting the result after execution of the task in Result class which stores the name of task and timestamp when the task completed.

class Result 
{
	private String name;
	private String timestamp;

	public Result(String name, String timestamp) {
		super();
		this.name = name;
		this.timestamp = timestamp;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getTimestamp() {
		return timestamp;
	}

	public void setTimestamp(String timestamp) {
		this.timestamp = timestamp;
	}

	@Override
	public String toString() {
		return "Result [name=" + name + ", value=" + timestamp + "]";
	}
}

In this example, we have submitted 5 tasks which are submitted to executor service using invokeAll() method. All tasks are executed at different time duration as there are only two threads in thread pool.

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

public class Main 
{
	public static void main(String[] args) throws InterruptedException 
	{
		ExecutorService executor = (ExecutorService) Executors.newFixedThreadPool(2);

		List<Task> taskList = new ArrayList<>();
		for (int i = 0; i < 5; i++) {
			Task task = new Task("Task-" + i);
			taskList.add(task);
		}
		
		//Execute all tasks and get reference to Future objects
		List<Future<Result>> resultList = null;

		try {
			resultList = executor.invokeAll(taskList);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		executor.shutdown();

		System.out.println("\n========Printing the results======");
		
		for (int i = 0; i < resultList.size(); i++) {
			Future<Result> future = resultList.get(i);
			try {
				Result result = future.get();
				System.out.println(result.getName() + ": " + result.getTimestamp());
			} catch (InterruptedException | ExecutionException e) {
				e.printStackTrace();
			}
		}
	}
}

Program output.

Task-0: Staring
Task-0: Waiting 7 seconds for results.
Task-1: Staring
Task-1: Waiting 1 seconds for results.
Task-2: Staring
Task-2: Waiting 2 seconds for results.
Task-3: Staring
Task-3: Waiting 3 seconds for results.
Task-4: Staring
Task-4: Waiting 4 seconds for results.

========Printing the results======

Task-0: 2019-05-23T12:56:33.692
Task-1: 2019-05-23T12:56:27.885
Task-2: 2019-05-23T12:56:29.887
Task-3: 2019-05-23T12:56:32.889
Task-4: 2019-05-23T12:56:36.890

Main thing to notice is that even if few tasks are completed, program does not start printing the results. We get the result only after all the tasks are completed.

Drop me your questions related to Java ExecutorService Callable Example in comments section.

Happy Learning !!

Was this post helpful?

Join 7000+ Fellow Programmers

Subscribe to get new post notifications, industry updates, best practices, and much more. Directly into your inbox, for free.

1 thought on “ExecutorService invokeAll()”

  1. While making an instance of ThreadPoolExecutor, what role the queue plays.
    Following is the code:

        
    private ExecutorService getExecutor() 
    {
      return new ThreadPoolExecutor
          (       
            mainThreads, mainThreads,
            60L, TimeUnit.SECONDS,
            new SynchronousQueue(),
            new ThreadFactory() {
                private int count;
                @Override
                public Thread newThread(Runnable r) {
                    return new Thread(r, "reprocessing-" + ++count);
                }
            },
            new ThreadPoolExecutor.DiscardPolicy()
          );
    
    Reply

Leave a Comment

HowToDoInJava

A blog about Java and its related technologies, the best practices, algorithms, interview questions, scripting languages, and Python.