掘金 后端 ( ) • 2024-04-19 12:58

CompletableFuture是Java 8引入的一个非常强大的并发工具,它实现了Future接口,并提供了更强大的异步操作能力。CompletableFuture可以手动完成并且可以构建异步执行的流水线。它的设计让它非常适合用来编写非阻塞的异步代码。

核心特性

  • 异步执行任务:允许你非阻塞地执行任务,不需要等待操作完成即可继续执行。
  • 链式调用:可以将多个CompletableFuture任务串联或组合起来,形成一个链或树。
  • 手动完成:可以手动完成一个任务,即可以手动设置它的结果或异常。
  • 组合式异步编程:提供了丰富的API,支持更复杂的异步编程模式,而不仅仅是简单地启动和等待。

源码解析(简化)

CompletableFuture的实现基于ForkJoinPool,利用了Java的ForkJoin框架来执行异步任务。关键的方法包括supplyAsyncthenApplythenAccept等,用于构建异步任务的执行流。

public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
    // 使用ForkJoinPool异步执行任务
    public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
        CompletableFuture<U> f = new CompletableFuture<U>();
        ForkJoinPool.commonPool().execute(() -> {
            try {
                f.complete(supplier.get());
            } catch (Throwable ex) {
                f.completeExceptionally(ex);
            }
        });
        return f;
    }
    // 其他方法...
}

代码演示

下面是一个示例,展示如何使用CompletableFuture来异步执行任务,并处理结果。

import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;

public class CompletableFutureDemo {
    
    public static void main(String[] args) {
        // 使用CompletableFuture异步执行一个供应者任务
        CompletableFuture<String> future = CompletableFuture.supplyAsync(new Supplier<String>() {
            @Override
            public String get() {
                // 模拟长时间运行的任务
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return "Hello, CompletableFuture!";
            }
        });
        
        // 注册一个回调函数,当异步任务完成时被调用
        future.thenAccept(result -> System.out.println(result));

        // 阻塞当前线程,等待异步操作完成
        future.join();
        
        System.out.println("任务完成!");
    }
}

注意事项

  • 异常处理CompletableFuture提供了exceptionally方法来处理异步执行中的异常。
  • 线程使用:默认情况下,CompletableFuture使用公共的ForkJoinPool,但可以通过重载的方法指定不同的执行器。
  • 阻塞与非阻塞joinget方法用于阻塞当前线程直到Future完成,但在CompletableFuture的异步编程模式中,更推荐使用非阻塞的方式,即通过注册回调函数来处理结果。

总结,CompletableFuture提供了一种强大且灵活的方式来处理异步编程,能够简化代码并提升性能。通过它提供的丰富API,开发者可以轻松实现复杂的异步逻辑,编写清晰且易于维护的并发程序。