CompletableFuture 解析:核心功能与异步编程案例

CompletableFuture‌是Java 8中引入的一个类,位于java.util.concurrent包中。它代表一个异步计算的结果,可以是已完成、正在进行或尚未开始。CompletableFuture的设计灵感来源于函数式编程中的Promises/Futures模式,旨在简化异步编程模型,提高代码的可读性和可维护性‌1。

基本概念和功能

CompletableFuture提供了一种灵活、类型安全的方式来表达异步操作的生命周期,包括创建、组合、处理结果以及处理异常。其主要功能包括:

  • 创建‌:可以通过completedFuture(T value)创建一个已经完成的状态的CompletableFuture,或者通过supplyAsync(Supplier<U> supplier, Executor executor)runAsync(Runnable runnable, Executor executor)异步执行任务。
  • 组合‌:可以使用thenApply(Function<? super T, ? extends U> fn)在当前CompletableFuture完成后应用给定的Function处理结果,返回一个新的CompletableFuture;thenAccept(Consumer<? super T> consumer)用于处理结果但不返回新的CompletableFuture;thenRun(Runnable runnable)用于在CompletableFuture完成后执行任务‌12。

历史背景和设计理念

CompletableFuture是对传统Future接口的扩展,旨在提供更灵活、更强大的异步任务处理能力。它实现了FutureCompletionStage接口,支持链式异步任务组合、异常处理和灵活的结果转换。CompletableFuture的设计灵感来源于函数式编程中的Promises/Futures模式,简化了异步编程模型,提高了代码的可读性和可维护性‌13。

使用案例

1. 基本异步任务

使用 supplyAsync 执行带返回值的异步任务:

public static void main(String[] args) throws Exception {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000); // 模拟耗时操作
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Result from async operation";
        });

        // 获取结果(阻塞)
        String result = future.get();
        System.out.println(result); // 输出: Result from async operation

    }

2. 无返回值的异步任务

使用 runAsync 执行无返回值的异步任务:

public static void main(String[] args) throws Exception {
        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Task completed");
        });
    }

3.组合多个 Future(并行执行)

使用 thenCombine 合并两个独立 Future 的结果:

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10);
        CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 20);

        CompletableFuture<Integer> combined = future1.thenCombine(future2, (a, b) -> a + b);

        System.out.println(combined.get()); // 输出: 30
    }

 4. 多个 Future 全部完成后执行

    public static void main(String[] args) throws Exception {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello")
                .thenApply(result -> result + " World")
                .thenApply(result -> result.toUpperCase());

        System.out.println(future.get()); // 输出: HELLO WORLD
    }

5. 多个 Future 全部完成后执行

使用 allOf 等待所有 Future 完成

CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> "Task1");
        CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> "Task2");
        CompletableFuture<String> task3 = CompletableFuture.supplyAsync(() -> "Task3");

        CompletableFuture<Void> allFutures = CompletableFuture.allOf(task1, task2, task3);

        // 获取所有结果
        CompletableFuture<List<String>> allResults = allFutures.thenApply(v -> {
            return Arrays.asList(task1.join(), task2.join(), task3.join());
        });

        allResults.get().forEach(System.out::println);
        // 输出:
        // Task1
        // Task2
        // Task3

6. 任意一个 Future 完成后执行

使用 anyOf 只要有一个 Future 完成就继续:

public static void main(String[] args) throws Exception {
        CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> {
            try { Thread.sleep(2000); } catch (Exception e) {}
            return "Task1";
        });
        CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> {
            try { Thread.sleep(1000); } catch (Exception e) {}
            return "Task2";
        });

        CompletableFuture<Object> anyResult = CompletableFuture.anyOf(task1, task2);
        System.out.println(anyResult.get()); // 输出: Task2(更快完成)
    }

7. 异步回调(非阻塞)

使用 whenComplete 或 handle 在 Future 完成时执行回调:

public static void main(String[] args) throws Exception {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            try { Thread.sleep(1000); } catch (Exception e) {}
            return "Result";
        });

        future.whenComplete((result, ex) -> {
            if (ex == null) {
                System.out.println("Completed: " + result);
            } else {
                System.out.println("Failed: " + ex.getMessage());
            }
        });

        // 主线程无需等待,可继续执行其他任务
        System.out.println("Main thread continues...");
    }

8. 自定义线程池

指定线程池执行异步任务:

public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newFixedThreadPool(4);

        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (Exception e) {

            }
            return "Async result";
        }, executor);

        System.out.println(future.get());
        executor.shutdown();
    }

9. 超时处理

使用 orTimeout 或 completeOnTimeout 设置超时:

public static void main(String[] args) throws Exception {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000);
            } catch (Exception e) {

            }
            return "Result";
        });

        try {
            // 超时1秒,将抛出 TimeoutException
            String result = future.orTimeout(2, TimeUnit.SECONDS).get();
            System.out.println(result);
        } catch (Exception e) {
            System.out.println("Operation timed out");
        }
    }

10.异常处理

使用 exceptionally 处理异常:

public static void main(String[] args) throws Exception {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            if (true) {
                throw new RuntimeException("Simulated error");
            }
            return "Success";
        }).exceptionally(ex -> {
            System.out.println("Caught exception: " + ex.getMessage());
            return "Default Value";
        });

        System.out.println(future.get()); // 输出: Default Value
    }

总结

CompletableFuture 通过链式调用和回调机制,提供了强大的异步编程能力,避免了传统回调地狱的问题。常见用法包括:

  • 异步执行任务(supplyAsync/runAsync
  • 链式处理结果(thenApply/thenAccept
  • 组合多个 Future(thenCombine/allOf/anyOf
  • 异常处理(exceptionally
  • 非阻塞回调(whenComplete/handle

合理使用 CompletableFuture 可以显著提升并发程序的可读性和性能。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值