【问题标题】:Can a ListenableFuture chain handle inner ExecutionException?ListenableFuture 链能否处理内部 ExecutionException?
【发布时间】:2018-02-28 19:04:11
【问题描述】:

我得到了一个 api (fnGrpc),它执行 gRPC 调用并返回解析为某个值 vListenableFuture(其实现是固定的并且不可修改)。

我想提供一个辅助函数 (fnHelper):

  1. 对 gRPC 结果进行一些转换处理,并返回一个ListenableFuture,解析为转换后的值t1

  2. 处理 gRPC 调用失败,并返回一些其他值 t2,而不是让 fnHelper 的调用者看到 ExecutionException

我可以使用Futures.transform()解决(1):

package myHelper;

ListenableFuture<T> fnHelper() {
  return Futures.transform(fnGrpc(), new Function<V, T>() {
    @Override
    public T apply(V v) {
      T t1 = f(v);
      return t1;
    }
  });
} 

和调用者:

package myApp;

// ...

try {
  T t = fnHelper().get();
} catch (ExecutionException | InterruptedException ex) {
  // ...
}

如何在 fnHelper 返回 ListenableFuture 并保持非阻塞状态的同时实现 (2)?

我可以让 fnHelper 自己创建一个额外的线程,在其中我会在 fnGrpc 上调用 .get(),但是还有其他方法可以避免这个额外的线程吗? p>

【问题讨论】:

    标签: java asynchronous java-8 guava future


    【解决方案1】:

    我不是 Guava 方面的专家,但您似乎可以使用相同的 Futures 实用程序类来做到这一点,特别是方法 catchingAsync,您可以在其中传递一个返回 ListenableFuture 的函数后备值 (t2):

    ListenableFuture<Integer> faultTolerantFuture = Futures.catchingAsync(originalFuture,
                           Exception.class, x -> immediateFuture(t2), executor);
    

    然后您应该能够使用 transform 方法将其链接起来,该方法进行转换:

    ListenableFuture<T> fnHelper() {
        return Futures.catching(Futures.transform(fnGrpc(), new Function<V, T>() {
            @Override
            public T apply(V v) {
                T t1 = f(v);
                return t1;
            }
        }),
        Exception.class, x -> immediateFuture(t2));
    }
    

    注意:在上一个sn-p中,我使用catching而不是catchingAsync来与您问题中的代码保持一致,并且我没有指定执行者。您可能需要使用带有 Async 后缀的方法进行非阻塞处理。

    【讨论】:

      猜你喜欢
      • 2013-01-21
      • 2017-07-29
      • 1970-01-01
      • 1970-01-01
      • 2015-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-29
      相关资源
      最近更新 更多