Executors & Futures
intermediate14 min readLesson 96 of 180
Submitting tasks, rethrowing ExecutionExceptions, and latch-based completion for deterministic assertions.
ExecutorService and Futures
Executors decouple task submission from thread management:
ExecutorService pool = Executors.newFixedThreadPool(4);
Future<Integer> f = pool.submit(() -> expensive());
Integer result = f.get(); // blocks until done
pool.shutdown(); // always โ or the JVM won't exit
Key behaviors:
submitreturns aFutureimmediately;get()joins that one task- tasks run on pool threads โ exceptions inside them do NOT crash your
thread;
get()rethrows them wrapped inExecutionException invokeAllsubmits a batch; the returned Futures complete in order- always
shutdown()โ try/finally orclose()(ExecutorService is AutoCloseable since Java 19)
Deterministic testing pattern: submit N tasks, get() each โ after all
gets return, every side effect is visible. Latches are the tool when
tasks must all finish before an assertion:
CountDownLatch done = new CountDownLatch(n);
// each task: work(); done.countDown();
done.await(); // wait for all n countDowns