Skip to main content

Executor Service

Virtual Threads vs WebFlux vs Platform Threads on Spring Boot 4.1: Benchmarks and a Decision Framework

Three identical Spring Boot 4.1.1 endpoints — I/O-bound and CPU-bound — re-benchmarked on JDK 25 under platform threads, virtual threads, and WebFlux. Real numbers, a benchmark-methodology bug caught and fixed along the way, an event-loop-starvation failure mode isolated CPU benchmarks miss, and a decision framework: if your service does X, pick Y, because Z.

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

Records, pattern-matching switch, virtual threads, sequenced collections, scoped values and structured concurrency from Java 21 to Java 25 LTS, each compiled and run on JDK 21, 25, 26 and 27: what is really final, when virtual threads stopped pinning, and what 26 and 27 mean for the road to Java 29.

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.