Scenario:
We’re building a service that fetches:
- Product details (takes ~1s)
- Pricing info (takes ~2s, sometimes slow → use timeout & fallback)
- Reviews (parallel fetch, then combine)
Finally, we combine everything into a single response string.
✅ Full Example Code
import java.util.concurrent.*;
public class AsyncProductService {
private static final ExecutorService executor = Executors.newFixedThreadPool(5);
public static void main(String[] args) throws Exception {
// Step 1: Fetch product details
CompletableFuture<String> productFuture = CompletableFuture.supplyAsync(() -> {
sleep(1000);
return "Product: Laptop";
}, executor);
// Step 2: Fetch price (with timeout + fallback)
CompletableFuture<String> priceFuture = CompletableFuture.supplyAsync(() -> {
sleep(3000); // simulate slow API
return "Price: $1200";
}, executor)
.completeOnTimeout("Price: unavailable (timeout fallback)", 2, TimeUnit.SECONDS)
.exceptionally(ex -> "Price: unavailable (error fallback)");
// Step 3: Fetch reviews (parallel task)
CompletableFuture<String> reviewsFuture = CompletableFuture.supplyAsync(() -> {
sleep(1500);
return "Reviews: ⭐⭐⭐⭐";
}, executor);
// Step 4: Combine product + price first
CompletableFuture<String> productWithPrice =
productFuture.thenCombine(priceFuture, (product, price) -> product + ", " + price);
// Step 5: Add reviews to final response
CompletableFuture<String> finalResponse =
productWithPrice.thenCombine(reviewsFuture, (partial, reviews) -> partial + ", " + reviews);
// Step 6: Wait and print final result
System.out.println("Final Response: " + finalResponse.get());
executor.shutdown();
}
private static void sleep(int ms) {
try { Thread.sleep(ms); } catch (InterruptedException e) {}
}
}
📝 Example Output
Final Response: Product: Laptop, Price: unavailable (timeout fallback), Reviews: ⭐⭐⭐⭐
(or, if price API responds in time:)
Final Response: Product: Laptop, Price: $1200, Reviews: ⭐⭐⭐⭐
⚡ Key Concepts Demonstrated
-
Parallel Execution →
supplyAsync
+thenCombine
- Dependent Pipelines → product first, then combine with price & reviews
-
Resilience →
completeOnTimeout
&exceptionally
- Thread Control → custom executor with 5 threads
-
Final Aggregation → all tasks merged into one
CompletableFuture
✅ This pattern is very close to real-world microservices aggregation, e.g., an API Gateway calling multiple services in parallel, handling timeouts gracefully, and returning a combined response.
Top comments (0)