java8的api提供了CompletableFuture。这个api的存在,极大了改变了java编程的模式。
以往的对比
除了自带的Future,我们接触最多的Future就是netty的。在之前的编程模型中,netty的Future的不同之处在于响应式,都是依靠注册事件,实现把遇到某种情况的代码写好,等触发。目前CompletableFuture也带了注册事件,但是编程的方式和原来相比有很大的区别。
- 更大数据化。大数据出现后,分布式运算也产生了,并且给大家不小的冲击,原来都是拿着数据给运算,现在拿着运算给数据。我们事先要编写好数据处理的流水线,然后再把运算给每个节点。于是编程上,出现了运算一个接着一个,最后统一拼接后,把数据流入。
- 更脚本化。大家写shell脚本的时候更注重操作部分。取数据之后,通过管道,后面的处理流程处理前面处理过的数据,依次往后。
注重编排
CompletableFuture的生成比较简单。主要是后面的继续工作。
CompletableFuture integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
return 1;
});
可以拿着前面的结果,继续做操作。
CompletableFuture integerCompletableFuture1 = integerCompletableFuture.thenApply((i) -> {
return i++;
});
在原先的基础上++。
CompletableFuture integerCompletableFuture3 = integerCompletableFuture1.thenCompose((i) -> {
return CompletableFuture.supplyAsync(() -> i + 1);
});
也可以通过thenCompose继续做流水线操作。
stringCompletableFuture.thenCombine(completableFuture1, (String s, char[] m) -> {
return s;
});
thenCombine可以让两个future执行完之后,拿着计算的数据,继续做操作。
CompletableFuture.allOf(stringCompletableFuture,completableFuture1);
allof可以等前面的结果都完成,有点类似countdownlatch的功能。
thenCompose和thenApply的区别
虽然两个都可以拿着原来的结果的数据继续运行,他们针对的场景不同,thenApply只能返回目前的处理后的结果,然后被CompletableFuture包起来。如果里面的处理过程是一个CompletableFuture的返回,就会出现CompletableFuture\的情况。总不能为此重写一份方法吧。thenCompose就可以解决这个问题,他的方法内要求返回CompletableFuture。并且我们拿到的返回值还是CompletableFuture的。这样就补充了thenApply的能力缺陷。
还有很多编排的方法就不列举了。
注重事件
CompletableFuture也有很多事件的方法,让我们了解某些事件的产生。
CompletableFuture stringCompletableFuture = CompletableFuture.supplyAsync(() -> {
return "hello";
}).whenComplete((String s, Throwable e) -> {
System.out.println(s);
});
可以在完成时获取到返回值和异常值。
stringCompletableFuture.exceptionally(Throwable::getMessage);
可以中间注册异常事件,并不用在完成事件里获取。
小结
CompletableFuture主要注重两个部分。
- 编排,如果处理完之后怎么处理,然后怎么继续操作。
- 事件注册,通过已有的事件,可以帮助我们获取到运行的状态。