天天看点

为什么有CompletableFuture为什么有CompletableFutureCompletableFuture

为什么有CompletableFuture

jdk5时代引入了Future,用来描述一个异步计算的结果。你可以使用isDone方法检查计算是否完成,或者使用get阻塞住调用线程,直到计算完成返回结果,你也可以使用cancel方法停止任务的执行

Futrue示例如下:

ExecutorService es = Executors.newFixedThreadPool(1);
Future<Integer> f = es.submit(() ->{
    // dosomething longtime
    return 100;
});
// while(!f.isDone())
// ;
f.get();
 
           

虽然Future以及相关使用方法提供了异步执行任务的能力,但是对于结果的获取却是很不方便,只能通过阻塞或者轮询的方式得到任务的结果。阻塞的方式显然和我们的异步编程的初衷相违背,轮询的方式又会耗费无谓的CPU资源,而且也不能及时地得到计算结果,为什么不能用观察者设计模式当计算结果完成及时通知监听者呢?

很多语言,比如Netty,自己扩展了Java的 Future接口,提供了addListener等多个扩展方法:

ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));
future.addListener(new ChannelFutureListener()
{
@Override
public void operationComplete(ChannelFuture future) throws Exception
{
if (future.isSuccess()) {
// SUCCESS
}
else {
// FAILURE
}
}
});

           

CompletableFuture

jdk8新增了CompletableFuture 来解决上述痛点,CompletableFuture类实现了CompletionStage和Future接口,所以你还是可以像以前一样通过阻塞或者轮询的方式获得结果,尽管这种方式不推荐使用。

public T get()
public T get(long timeout, TimeUnit unit)
public T getNow(T valueIfAbsent)
public T join()

           

join返回计算的结果或者抛出一个unchecked异常(CompletionException),它和get对抛出的异常的处理有些细微的区别,你可以运行下面的代码进行比较:

点评: get与join功能差不多,当没有异常时都返回计算的结果,区别在于如果计算过程中出现了异常,join兜底异常是CompletionException,get兜底异常是ExecutionException

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
int i = 1/0;
return 100;
});
//future.join();
future.get();

           
方法 说明
thenApply(Function f) 当前阶段正常完成之后,返回一个新的阶段,新的阶段把当前阶段的结果作为参数输入;
thenConsume(Consumer c) 当前阶段完成之后,结果作为参数输入,直接消费掉,得到不返回结果的完成阶段;
thenRun(Runnable action) 不接受参数,只是继续执行任务,得到一个新的完成阶段;
thenCombine(otherCompletionStage,BiFunction) 当两个完成阶段都完成的时候,执行BIFunction,返回一个新的阶段;
thenAcceptBoth(OtherCompletionStage, BiConsumer) 两个完成阶段都完成之后,对两个结果进行消费;
runAfterBoth(OtherCompletionStage,Runable) 两个完成阶段都完成之后,执行一个动作;
applyToEither(OtherCompletionStage,Function) 两个完成阶段的任何一个执行结束,进入函数操作,并返回一个新的阶段
acceptEither(OtherCompletionStage,Consumer) 两个完成阶段的任何一个执行结束,消费掉,返回一个空返回值的完成阶段
runAfterEither(OtherCompletionStage,Runable) 两个完成阶段的任何一个结束,执行一个动作,返回一个空返回值的完成阶段
thenCompose(Function) 当前阶段完成,返回值作为参数,进行函数运算,然后结果作为一个新的完成阶段
exceptionally(Function) 无论当前阶段是否正常完成,消费掉异常,然后返回值作为一个新的完成阶段
whenComplete handle 无论当前完成阶段是否正常结束,都执行一个BIFunction的函数,并返回一个新结果作为一个新的完成阶段
toCompletableFuture 转换为ComplatableFuture

参考文章 :https://www.cnblogs.com/tian666/p/7840232.html