【发布时间】:2016-12-09 06:06:57
【问题描述】:
我努力了,但没有找到任何文章或博客明确比较ListenableFuture和CompletableFuture,并提供了很好的分析。
所以如果有人能解释或指向我这样的博客或文章,那对我来说真的很好。
【问题讨论】:
-
gauva 团队关于ListenableFuture的博客
我努力了,但没有找到任何文章或博客明确比较ListenableFuture和CompletableFuture,并提供了很好的分析。
所以如果有人能解释或指向我这样的博客或文章,那对我来说真的很好。
【问题讨论】:
Guava AbstractFuture 有其局限性:
Listener 是列表,但通常只使用 1 个 - 矫枉过正。如果需要多个侦听器,请在下一阶段处理它,或者考虑消息传递。
setException 将返回值设置为 Exception,因此用户必须使用 instanceof 来区分 get() 的 Exception 与否,就像 guava AbstractFuture 所做的那样。
在 Future 管道中,太多层 addListener() 使代码难以阅读。
我更喜欢CompletableFuture.supply().thenApply().thenAccept().handle()
【讨论】:
ListenableFuture 和 CompletableFuture 都比其父类 Future 具有优势,它允许调用者以一种或另一种方式“注册”异步操作完成时调用的回调。
使用Future,您可以这样做:
ExecutorService executor = ...;
Future f = executor.submit(...);
f.get();
f.get() 被阻塞,直到异步操作完成。
使用 ListenableFuture,您可以像这样注册回调:
ListenableFuture listenable = service.submit(...);
Futures.addCallback(listenable, new FutureCallback<Object>() {
@Override
public void onSuccess(Object o) {
//handle on success
}
@Override
public void onFailure(Throwable throwable) {
//handle on failure
}
})
使用 CompletableFuture,您还可以注册回调 任务已完成,但它与 ListenableFuture 的不同之处在于它可以从任何希望它完成的线程中完成。
CompletableFuture completableFuture = new CompletableFuture();
completableFuture.whenComplete(new BiConsumer() {
@Override
public void accept(Object o, Object o2) {
//handle complete
}
}); // complete the task
completableFuture.complete(new Object())
当线程对任务调用完成时,如果任务尚未完成,则从调用 get() 接收到的值设置为参数值。
【讨论】:
toCompletableFuture)是危险的,因为它公开了complete 方法。又一个我们期望 Oracle 提供的没有经过深思熟虑的垃圾的例子。
CompletionStage 如果扩展 Future 并且不暴露 toCompletableFuture 会很好。然后他们可以将其命名为有意义的名称,例如“ChainableFuture”。
Future 和 ListenableFuture 是接口,而 CompletableFuture 是实现 Future 的类
CompletableFuture 并覆盖它以在 toCompletableFuture 上引发异常(正如您的链接中的讨论所暗示的那样),那么流利的方法就会中断,因为大多数流利的方法实际上调用 toCompletableFuture 方法来完成他们的工作。 ListenableFuture 的噪音少得多,“危险”的东西也少了。