CompletableFuture由Java 8提供,是实现异步化的工具类,上手难度较低,且功能强大,支持通过函数式编程的方式对各类操作进行组合编排。相比于ListenableFuture,CompletableFuture有效提升了代码的可读性。
CompletableFuture中包含两个字段:result和stack。result用于存储当前CF的结果,stack(Completion)表示当前CF完成后需要触发的依赖动作(Dependency Actions),去触发依赖它的CF的计算,依赖动作可以有多个(表示有多个依赖它的CF),以栈(Treiber stack)的形式存储,stack表示栈顶元素。
CompletableFuture实现了两个接口分别是Future和CompletionStage。Future表示异步计算的结果,CompletionStage用于表示异步执行过程中的一个步骤(Stage),这个步骤可能是由另外一个CompletionStage触发的,随着当前步骤的完成,也可能会触发其他一系列CompletionStage的执行。从而我们可以根据实际业务对这些步骤进行多样化的编排组合,CompletionStage接口正是定义了这样的能力,我们可以通过其提供的thenAppy、thenCompose等函数式编程方法来组合编排这些步骤。CompletableFuture的功能主要体现在他的CompletionStage。
可以实现如下等功能
-
转换(thenCompose)
-
组合(thenCombine)
-
消费(thenAccept)
-
运行(thenRun)。
-
带返回的消费(thenApply)
根据CompletableFuture所依赖的前置任务的数量,有不同的编码方式。
1. 不依赖其他CompletableFuture来创建新的CompletableFuture
ExecutorService executor = Executors.newFixedThreadPool(10);
//第一种方式:直接发起异步调用task
CompletableFuture<String> task = CompletableFuture.supplyAsync(() -> {
return "result";
}, executor);
//第二种方式:创建一个状态为已完成的task
CompletableFuture<String> task = CompletableFuture.completedFuture("result");
//第三种方式:实例化一个task,通过complete()方法完成该task
CompletableFuture<String> task = new CompletableFuture<>();
task.complete("success");
2. 依赖单个CompletableFuture来创建新的CompletableFuture
例如taskB要依赖taskA的结果
CompletableFuture<String> taskB = taskA.thenApply(resultA -> {
//......
return "resultB";
});
3. 依赖两个CompletableFuture来创建新的CompletableFuture
例如taskC要依赖taskA和taskB的结果
CompletableFuture<String> taskC = taskA.thenCombine(taskB, (resultA, resultB) -> {
//....
return "resultC";
});
4. 依赖多个CompletableFuture来创建新的CompletableFuture
通过allOf
或anyOf
方法来实现,区别是当需要多个依赖全部完成时使用allOf
,当多个依赖中的任意一个完成即可时使用anyOf
CompletableFuture<Void> taskD = CompletableFuture.allOf(taskA, taskB, taskC);
CompletableFuture<String> result = taskD.thenApply(v -> {
//这里的join并不会阻塞,因为传给thenApply的函数是在taskA、taskB、taskC全部完成时,才会执行
resultA = cfA.join();
resultB = cfB.join();
resultC = cfC.join();
//根据resultA、resultB、resultC组装最终result;
return "result";
});
注:在异步场景中不要嵌套任何可能存在长耗时的同步操作,否则会影响吞吐量。