Courses/Java/CompletableFuture

    Lesson 28 • Advanced

    CompletableFuture & Async Programming

    Chain async operations and handle results with CompletableFuture.

    Before You Start

    You need Multithreading (Lesson 26), Lambda Expressions (Lesson 22), and Streams API (Lesson 21). CompletableFuture is Java's Promise — it combines async execution with functional-style chaining.

    What You'll Learn

    • ✅ supplyAsync() and runAsync()
    • ✅ thenApply(), thenAccept(), thenRun()
    • ✅ thenCompose() vs thenCombine()
    • ✅ Exception handling: exceptionally(), handle()
    • ✅ allOf() and anyOf() for parallel tasks

    1️⃣ From Callbacks to Pipelines

    💡 Analogy: Food Delivery App

    supplyAsync() is like placing an order — it starts in the background. thenApply() is like "when food arrives, add tip to receipt." thenCompose() is like "when food arrives, order dessert from same place" (sequential async). thenCombine() is ordering food and drinks simultaneously, combining when both arrive. exceptionally() is your backup — "if order fails, get pizza."

    Try It: Async Chaining Basics

    Try it Yourself »
    JavaScript
    // CompletableFuture — Async Chaining
    console.log("=== CompletableFuture Basics ===\n");
    
    // 1. supplyAsync + thenApply (simulated with Promises)
    console.log("1. supplyAsync + thenApply:");
    let fetchUser = Promise.resolve({ id: 1, name: "Alice", age: 28 });
    fetchUser
        .then(user => { console.log("  Fetched: " + user.name); return user.name.toUpperCase(); })
        .then(name => console.log("  Transformed: " + name));
    
    // 2. Chaining multiple steps
    console.log("\n2. CHAINING OPERATIONS:");
    Promis
    ...

    2️⃣ thenCompose vs thenCombine

    thenCompose = sequential async (flatMap). Use when second operation depends on first: fetch user → then fetch user's orders. thenCombine = parallel async. Use when two operations are independent: fetch price AND fetch discount → calculate total.

    Try It: Compose, Combine & Error Handling

    Try it Yourself »
    JavaScript
    // thenCompose, thenCombine & Error Handling
    console.log("=== Compose & Combine ===\n");
    
    // 1. thenCompose (sequential — flatMap)
    console.log("1. thenCompose (SEQUENTIAL ASYNC):");
    function getUserById(id) { return Promise.resolve({ id, name: "User-" + id }); }
    function getOrdersForUser(user) { return Promise.resolve(["Order-A", "Order-B"]); }
    
    getUserById(42)
        .then(user => { console.log("  Step 1: Found " + user.name); return getOrdersForUser(user); })
        .then(orders => console.log("  St
    ...

    Try It: Real-World Async Patterns

    Try it Yourself »
    JavaScript
    // Real-World Async Patterns
    console.log("=== Async Patterns ===\n");
    
    // 1. Microservice aggregation
    console.log("1. MICROSERVICE AGGREGATION:");
    function fetchUserProfile(id) { return Promise.resolve({ name: "Alice", role: "admin" }); }
    function fetchUserOrders(id) { return Promise.resolve([{ id: 101, total: 59.99 }, { id: 102, total: 124.50 }]); }
    function fetchRecommendations(id) { return Promise.resolve(["Product A", "Product B", "Product C"]); }
    
    let userId = 42;
    Promise.all([
        fetchUse
    ...

    Common Mistakes

    Using get() without timeout: future.get() blocks forever. Always use get(5, TimeUnit.SECONDS).
    Ignoring exceptionally() return: It returns a new CompletableFuture. Chain from it or your error handling is lost.
    Common ForkJoinPool for I/O: Blocking I/O starves other tasks. Use dedicated executor.
    thenApply vs thenCompose: If your function returns CompletableFuture, use thenCompose to avoid nested futures.

    Pro Tips

    💡 handle() vs exceptionally(): handle() receives both result and exception — use for logging regardless of outcome.

    💡 orTimeout() (Java 9+): future.orTimeout(5, SECONDS) — no more hanging futures.

    💡 allOf() returns Void — collect results with futures.stream().map(CF::join).toList().

    📋 Quick Reference

    MethodTypePurpose
    supplyAsync()CreateStart async with return value
    thenApply()TransformMap result (like .map())
    thenCompose()ChainSequential async (flatMap)
    thenCombine()CombineParallel async merge
    exceptionally()ErrorHandle errors with fallback

    🎉 Lesson Complete!

    You've mastered async programming with CompletableFuture!

    Next: Memory Management & JVM Garbage Collection.

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service