java 36 lines · 6 steps

Coalescing duplicate requests in Java

How a ConcurrentHashMap of in-flight futures collapses concurrent calls for the same key into one load.

Explained by highlit
1public class RequestCoalescer<K, V> {
2 
3 private final ConcurrentHashMap<K, CompletableFuture<V>> inFlight = new ConcurrentHashMap<>();
4 private final Function<K, V> loader;
5 private final Executor executor;
6 
7 public RequestCoalescer(Function<K, V> loader, Executor executor) {
8 this.loader = loader;
9 this.executor = executor;
10 }
11 
12 public CompletableFuture<V> get(K key) {
13 CompletableFuture<V> existing = inFlight.get(key);
14 if (existing != null) {
15 return existing;
16 }
17 
18 CompletableFuture<V> created = new CompletableFuture<>();
19 CompletableFuture<V> raced = inFlight.putIfAbsent(key, created);
20 if (raced != null) {
21 return raced;
22 }
23 
24 CompletableFuture.supplyAsync(() -> loader.apply(key), executor)
25 .whenComplete((value, error) -> {
26 inFlight.remove(key, created);
27 if (error != null) {
28 created.completeExceptionally(error);
29 } else {
30 created.complete(value);
31 }
32 });
33 
34 return created;
35 }
36}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Sharing a future per key lets many callers await one computation instead of triggering redundant work.
  2. 2putIfAbsent turns a check-then-act race into a single atomic claim, so exactly one caller starts the load.
  3. 3Removing the entry on completion keeps the map bounded and lets future callers trigger a fresh load.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Coalescing duplicate requests in Java — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code