可听未来与可理解未来

2022-08-31 12:46:47

我努力尝试,但没有找到任何文章或博客可以清楚地比较和,并提供良好的分析。ListenableFutureCompletableFuture

因此,如果有人可以解释或指出我这样的博客或文章,那对我来说将是非常好的。


答案 1

ListenableFutureComppletableFuture都比其父类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() 的调用接收的值将使用参数值进行设置。

阅读全文


答案 2

番石榴抽象未来有其局限性:

  1. 监听器是列表,但通常只有1个使用 - 过度杀戮。如果需要多个侦听器,请在下一阶段内处理它,或者考虑消息传递。

  2. setException 将返回值设置为 Exception,因此用户必须使用 instanceof 来区分 Exception 或不像 guava AbstractFuture 那样。get()

  3. 在 Future 管道中,层太多会使代码难以阅读。addListener()

我更喜欢CompletableFuture.supply().thenApply().thenAccept().handle()


推荐