ExecutorService.invokeAll submits a whole collection of tasks and blocks until all of them complete, returning their Futures in the same order the tasks were given. That fixed ordering is what makes the collected results deterministic.
ExecutorService pool = Executors.newFixedThreadPool(2);
List<Callable<Integer>> tasks = List.of(() -> 2 * 2, () -> 3 * 3, () -> 4 * 4);
List<Future<Integer>> futures = pool.invokeAll(tasks);
List<Integer> results = new ArrayList<>();
for (Future<Integer> f : futures) results.add(f.get());
pool.shutdown();
System.out.println("Results in submission order: " + results);
Results in submission order: [4, 9, 16]
Run this yourself in the Online Java Compiler, spin up a live REST API in the API Sandbox, or practise with Java interview questions.
Published 2026-09-27