To submit multiple tasks and get results using invokeAll
in Java, you can make use of the ExecutorService
. The invokeAll
method submits a collection of Callable
tasks to the executor and waits for all of them to complete. Once completed, it returns a list of Future
objects, each representing the result of a corresponding task.
Here’s how it works:
- Create a collection of
Callable
tasks: These tasks are units of work that the executor will execute in parallel. - Submit the tasks using
invokeAll
: TheinvokeAll
method blocks until all tasks are complete or timed out. - Retrieve the results from the
Future
objects: EachFuture
object allows you to get the result of its corresponding task or check for exceptions.
Example Code
package org.kodejava.util.concurrent;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class InvokeAllExample {
public static void main(String[] args) {
// Create a fixed thread pool
ExecutorService executorService = Executors.newFixedThreadPool(3);
// Create a collection of Callable tasks
List<Callable<String>> tasks = new ArrayList<>();
tasks.add(() -> {
// Simulate doing some work
Thread.sleep(1000);
return "Task 1 completed";
});
tasks.add(() -> {
Thread.sleep(2000);
return "Task 2 completed";
});
tasks.add(() -> {
Thread.sleep(1500);
return "Task 3 completed";
});
try {
// Submit the tasks and wait for all of them to complete
List<Future<String>> results = executorService.invokeAll(tasks);
// Iterate through the futures to retrieve the results
for (Future<String> future : results) {
try {
// Get the result of each task
System.out.println(future.get());
} catch (ExecutionException e) {
System.err.println("Task encountered an issue: " + e.getMessage());
}
}
} catch (InterruptedException e) {
System.err.println("Task execution was interrupted: " + e.getMessage());
} finally {
// Shutdown the executor service
executorService.shutdown();
}
}
}
Explanation:
- ExecutorService:
- A thread pool is created (
Executors.newFixedThreadPool(3)
), which allows up to 3 threads to run simultaneously.
- A thread pool is created (
- List of Callable tasks:
- Each task implements the
Callable
interface and returns a result. For example, the tasks simulate work byThread.sleep()
and return a string.
- Each task implements the
- invokeAll Method:
executorService.invokeAll(tasks)
submits all tasks at once and blocks until all tasks are complete.
- Retrieving Results:
- The method returns a list of
Future
objects, wherefuture.get()
is used to retrieve the result of each task.
- The method returns a list of
- Exceptions:
- Handle
InterruptedException
(if the current thread is interrupted) andExecutionException
(if a task fails with an exception).
- Handle
- Shutdown the Executor:
- Always call
shutdown()
to properly terminate the executor service and release resources.
- Always call
Output:
Task 1 completed
Task 3 completed
Task 2 completed
(Note: The order may vary since the tasks run concurrently.)
Keynotes:
- Use
ExecutorService
to manage thread pools efficiently. - The
invokeAll
method blocks until all tasks are complete. - Handle exceptions like
InterruptedException
andExecutionException
. - Always shut down the executor service to free resources.