哪些Java案例展示了CompletableFuture?

wen java案例 2

本文目录导读:

哪些Java案例展示了CompletableFuture?

  1. 案例1:基础异步执行与结果获取
  2. 案例2:任务链式编排(thenApply / thenCompose)
  3. 案例3:两个独立任务的并行合并(thenCombine)
  4. 案例4:任务完成后的回调(thenAccept / whenComplete)
  5. 案例5:异常处理与恢复(exceptionally / handle)
  6. 案例6:超时控制(orTimeout / completeOnTimeout)
  7. 案例7:等待多个任务全部完成(allOf)
  8. 案例8:任意一个任务完成立即处理(anyOf)
  9. 案例9:手动完成 Future(complete / completeExceptionally)

案例1:基础异步执行与结果获取

场景:异步查询用户信息,并在主线程中阻塞等待结果。

import java.util.concurrent.CompletableFuture;
public class BasicExample {
    public static void main(String[] args) throws Exception {
        // 异步执行任务,返回 CompletableFuture
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            // 模拟耗时操作
            try { Thread.sleep(2000); } catch (InterruptedException e) { }
            return "用户数据";
        });
        // 阻塞获取结果(类似 Future.get())
        String result = future.get();
        System.out.println(result); // 输出:用户数据
    }
}

说明supplyAsync 将任务提交到 ForkJoinPool 线程池,get() 阻塞等待完成。


案例2:任务链式编排(thenApply / thenCompose)

场景:先查询用户ID,再根据ID查询用户详情。

public class ChainExample {
    public static void main(String[] args) throws Exception {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            return "user123"; // 获取用户ID
        }).thenApply(userId -> {
            // 通过ID查询用户信息(同步或异步)
            return "用户:" + userId + " 的详细信息";
        }).thenApply(detail -> {
            return detail + "(已格式化)";
        });
        System.out.println(future.get()); 
        // 输出:用户:user123 的详细信息(已格式化)
    }
}

说明thenApply 将前一步的结果作为输入,同步执行转换,若需异步转换则用 thenCompose


案例3:两个独立任务的并行合并(thenCombine)

场景:同时查询用户信息和订单信息,合并结果。

public class CombineExample {
    public static void main(String[] args) throws Exception {
        CompletableFuture<String> userFuture = CompletableFuture.supplyAsync(() -> {
            return "用户信息";
        });
        CompletableFuture<String> orderFuture = CompletableFuture.supplyAsync(() -> {
            return "订单信息";
        });
        // 两个任务完成后合并结果
        CompletableFuture<String> combined = userFuture.thenCombine(orderFuture, 
            (user, order) -> user + " + " + order);
        System.out.println(combined.get()); 
        // 输出:用户信息 + 订单信息
    }
}

说明thenCombine 等待两个 Future 都完成,然后使用 BiFunction 合并。


案例4:任务完成后的回调(thenAccept / whenComplete)

场景:异步执行后,打印日志或更新UI,不返回新结果。

public class CallbackExample {
    public static void main(String[] args) throws Exception {
        CompletableFuture.supplyAsync(() -> {
            return "任务结果";
        }).thenAccept(result -> {
            // 消费结果,无返回值
            System.out.println("日志记录:" + result);
        });
        // 或者使用 whenComplete(无论成功/失败都会执行)
        CompletableFuture.supplyAsync(() -> {
            if (Math.random() > 0.5) throw new RuntimeException("出错");
            return "成功";
        }).whenComplete((result, ex) -> {
            if (ex != null) {
                System.out.println("出错了:" + ex.getMessage());
            } else {
                System.out.println("结果:" + result);
            }
        });
    }
}

说明thenAccept 只处理成功结果;whenComplete 同时处理成功和异常。


案例5:异常处理与恢复(exceptionally / handle)

场景:任务可能抛出异常,提供默认值或优雅降级。

public class ErrorHandlingExample {
    public static void main(String[] args) throws Exception {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            if (true) throw new RuntimeException("数据库异常");
            return "正常数据";
        }).exceptionally(ex -> {
            System.out.println("异常:" + ex.getMessage());
            return "降级数据"; // 提供默认值
        });
        // 或者使用 handle(无论成功/失败都调用,可以转换结果)
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            return "正常";
        }).handle((result, ex) -> {
            if (ex != null) return "错误:" + ex.getMessage();
            return "" + result;
        });
        System.out.println(future.get()); // 输出:降级数据
    }
}

说明exceptionally 只在异常时执行;handle 类似 finally,但可返回新结果。


案例6:超时控制(orTimeout / completeOnTimeout)

场景:防止任务长时间阻塞,指定超时时间。

import java.util.concurrent.TimeUnit;
public class TimeoutExample {
    public static void main(String[] args) throws Exception {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            try { Thread.sleep(5000); } catch (InterruptedException e) { }
            return "慢速数据";
        }).orTimeout(2, TimeUnit.SECONDS); // 2秒超时则抛出 TimeoutException
        // 或者用 completeOnTimeout 提供默认值
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            try { Thread.sleep(5000); } catch (InterruptedException e) { }
            return "慢速数据";
        }).completeOnTimeout("默认值", 2, TimeUnit.SECONDS);
        System.out.println(future2.get()); // 2秒后输出:默认值
    }
}

说明:Java 9+ 新增 orTimeoutcompleteOnTimeout,前者超时抛异常,后者返回默认值。


案例7:等待多个任务全部完成(allOf)

场景:批量查询多个服务,全部完成后汇总。

public class AllOfExample {
    public static void main(String[] args) throws Exception {
        CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> "A");
        CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> "B");
        CompletableFuture<String> task3 = CompletableFuture.supplyAsync(() -> "C");
        // 等待所有任务完成
        CompletableFuture<Void> allDone = CompletableFuture.allOf(task1, task2, task3);
        // 阻塞直到全部完成
        allDone.get();
        // 单独获取每个结果
        System.out.println(task1.get() + task2.get() + task3.get()); // 输出:ABC
    }
}

说明allOf 返回 CompletableFuture<Void>,需手动合并结果。


案例8:任意一个任务完成立即处理(anyOf)

场景:调用多个供应商,使用最先返回的结果(类似熔断降级)。

public class AnyOfExample {
    public static void main(String[] args) throws Exception {
        CompletableFuture<String> fastService = CompletableFuture.supplyAsync(() -> {
            try { Thread.sleep(1000); } catch (InterruptedException e) { }
            return "快速服务";
        });
        CompletableFuture<String> slowService = CompletableFuture.supplyAsync(() -> {
            try { Thread.sleep(3000); } catch (InterruptedException e) { }
            return "慢速服务";
        });
        // 任意一个完成即返回
        CompletableFuture<Object> any = CompletableFuture.anyOf(fastService, slowService);
        System.out.println(any.get()); // 输出:1秒后的"快速服务"
    }
}

说明anyOf 返回 Object 类型,实际是第一个完成的任务的结果。


案例9:手动完成 Future(complete / completeExceptionally)

场景:在回调或外部事件中主动设置结果。

public class ManualCompleteExample {
    public static void main(String[] args) throws Exception {
        CompletableFuture<String> future = new CompletableFuture<>();
        // 模拟异步线程手动完成
        new Thread(() -> {
            try { Thread.sleep(2000); } catch (InterruptedException e) { }
            future.complete("手动完成的数据"); // 手动设置结果
        }).start();
        System.out.println(future.get()); // 2秒后输出:手动完成的数据
    }
}

说明complete 设置成功结果,completeExceptionally 设置异常。


场景 方法
基础异步执行 supplyAsync / runAsync
链式转换(同步) thenApply
链式转换(异步) thenCompose
并行合并两个任务 thenCombine
结果消费 / 回调 thenAccept / whenComplete
异常处理 exceptionally / handle
超时控制 orTimeout / completeOnTimeout
等待所有任务完成 allOf
任意一个任务完成 anyOf
手动完成 Future complete / completeExceptionally

这些案例覆盖了日常开发中 90% 以上的异步编排需求。

抱歉,评论功能暂时关闭!