Skip to main content

Executor Service

Java 21 to Java 25 LTS: Every Feature You Actually Need to Know

A practical walkthrough of the headline features landing in Java 21 (LTS) through Java 25 (LTS): records, pattern matching, virtual threads, sequenced collections, scoped values, and structured concurrency — with runnable examples and AI prompts you can copy straight into Claude or ChatGPT to migrate your own code.

Java’s ExecutorService.invokeAny(): Winning the Race for the First Result

In the world of concurrent programming, we often face scenarios where we need to perform the same task in multiple ways, but we only care about the first successful result. Imagine querying three different microservices for the same piece of data. You don’t care which service responds, as long as you get the data as quickly as possible. Once you have it, the other requests become redundant. How do you efficiently manage this “race”? You could manually spin up threads, use a CountDownLatch or a Phaser, and manage a shared result variable with locks. But that’s complicated and error-prone. Fortunately, Java’s ExecutorService provides a clean, powerful, and built-in solution: the invokeAny() method. Let’s dive into how invokeAny() works and how you can use it to write cleaner, more efficient concurrent code. What is ExecutorService.invokeAny()? The invokeAny() method is a blocking operation that submits a collection of Callable tasks to an ExecutorService. It doesn’t wait for all of them to finish. Instead, it waits for the first task to complete successfully (i.e., without throwing an exception) and returns its result. As soon as one task finishes, invokeAny() returns its result and immediately attempts to cancel all other running or pending tasks. This “fire-and-forget-the-rest” behavior makes it the perfect tool for tasks involving redundancy and speed.