CompletableFuture是对Future的扩展和增强。CompletableFuture实现了Future接口,并在此基础上进行了丰富的扩展,完美弥补了Future的局限性,同时CompletableFuture实现了对任务编排的能力。借助这项能力,可以轻松地组织不同任务的运行顺序、规则以及方式。从某种程度上说,这项能力是它的核心能力。而在以往,虽然通过CountDownLatch等工具类也可以实现任务的编排,但需要复杂的逻辑处理,不仅耗费精力且难以维护。
依赖关系
thenApply():把前面任务的执行结果,交给后面的Function
thenCompose():用来连接两个有依赖关系的任务,结果由第二个任务返回
and集合关系
thenCombine():合并任务,有返回值
thenAccepetBoth():两个任务执行完成后,将结果交给thenAccepetBoth处理,无返回值
runAfterBoth():两个任务都执行完成后,执行下一步操作(Runnable类型任务)
or聚合关系
applyToEither():两个任务哪个执行的快,就使用哪一个结果,有返回值
acceptEither():两个任务哪个执行的快,就消费哪一个结果,无返回值
runAfterEither():任意一个任务执行完成,进行下一步操作(Runnable类型任务)
并行执行
allOf():当所有给定的 CompletableFuture 完成时,返回一个新的 CompletableFuture
anyOf():当任何一个给定的CompletablFuture完成时,返回一个新的CompletableFuture
结果处理
whenComplete:当任务完成时,将使用结果(或 null)和此阶段的异常(或 null如果没有)执行给定操作
exceptionally:返回一个新的CompletableFuture,当前面的CompletableFuture完成时,它也完成,当它异常完成时,给定函数的异常触发这个CompletableFuture的完成
CompletableFuture–小窍门
1.所有的thenXXX都只能处理正确结果。Whencomplete和handler可以处理正确和错误的结果。
2.如果方法名中有accept,那末表示只能接受结果,不能返回新的结果
3.如果方法名中有apply,那么表示可以返回新的结果
4.如果方法名中有run,表示既不能接收结果,也不能返回结果。只在合适的时机被触发。
一些练习:
package com.one;
import java.util.concurrent.CompletableFuture;
/**
* <p>文件名称:TestCompeleteFuture</p>
* <p>文件描述:TODO</p>
* <p>公司名称:安徽皖通邮电股份有限公司 </p>
* <p>完成日期:2022年07年05日 08:55:26</p>
* author 王韵通
*/
public class TestCompeleteFuture {
public static void main(String[] args) {
CompletableFuture<String> future=new CompletableFuture<>();
future.complete("OK");
//所有以thenXXX开头的方法都用于处理正确结果
//因为第一级的回调没有返回结果,所以第二级回调收到的参数是null
future.thenAccept(result-> System.out.println(result))//ok
.thenAccept(result-> System.out.println(result));//null
future.thenApply(result->{
System.out.println(result);
return "Processed";//第一级的回调中返回了新的结果
}).thenAccept(result->{
System.out.println(result);
});
future.thenCompose(result->{
//返回一个新的CompletableFuture
return CompletableFuture.completedFuture(result+100);
}).thenAccept(System.out::println);
future.thenApply(result->{
return result+100;
}).thenAccept(System.out::println);
//thenApply中是以同步的方式返回新的结果;而thenCompose
//是以异步的方式返回新的结果
CompletableFuture<Integer> future1 = new CompletableFuture<>();
CompletableFuture<Integer> future2 = new CompletableFuture<>();
future1.complete(10);
future2.complete(20);
/**
* 将两个future合并,当他们都执行完毕后触发互调
* 再回调中返回一个新的结果
*/
future1.thenCombine(future2,(result1,result2)->result1+result2)
.thenAccept(System.out::println);
/**
*
*/
future1
.thenAcceptBoth(future2,(r1,r2)-> System.out.println(r1*r2))
.thenAccept(System.out::println);//输出null
CompletableFuture<Integer> future3 = new CompletableFuture<>();
future3.complete(20);
future3.whenComplete((result,number)->{
if(number!=null){
System.out.println(result);
}else{
System.out.println("buxing");
}
});
//默认情况下,回调方法和future.complete()是在同一个线程中运行
CompletableFuture<String> f = new CompletableFuture<>();
f.thenApply(result->{
System.out.println("L2"+Thread.currentThread());
return result;
}).thenAcceptAsync(r->{
System.out.println("L3"+Thread.currentThread());
});
System.out.println("L1"+Thread.currentThread());
f.complete("");
}
}