使用两种不同类型的Guava ListenableFutures的结果

sdg*_*sdh 11 java future guava

我有两个在其他线程上完成的ListenableFutures.每个未来都是不同的类型,我希望在它们完整时使用它们的两个结果.

有没有一种优雅的方式来处理这个使用番石榴?

fid*_*ido 9

如果您想要某种类型的安全性,您可以执行以下操作:

class Composite {
  public A a;
  public B b;
}

public ListenableFuture<Composite> combine(ListenableFuture<A> futureA, 
                                           final ListenableFuture<B> futureB) {

  return Futures.transform(futureA, new AsyncFunction<A, Composite>() {
    public ListenableFuture<Composite> apply(final A a) throws Exception {
      return Futures.transform(futureB, new Function<B, Compisite>() {
        public Composite apply(B b) {
          return new Composite(a, b);
        }
      }
    } 
  }

}

ListenableFuture<A> futureA = ...
ListenableFuture<B> futureB = ...

ListenableFuture<Composite> result = combine(futureA, futureB);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,如果你愿意,Composite可以Pair<A, B>来自Apache Commons.

此外,未来任何一方的失败都将导致未来的合并失败.

另一个解决方案是看看Spotify团队的Trickle.GitHub自述文件有一个示例,显示了类似问题的解决方案.

毫无疑问是其他解决方案,但这是我脑海中浮现的解决方案.


JB *_*zet 4

Runnable listener = new Runnable() {
    private boolean jobDone = false;

    @Override
    public synchronized void run() {
        if (jobDone || !(future1.isDone() && future2.isDone())) {
            return;
        }
        jobDone = true;
        // TODO do your job
    }
};
future1.addListener(listener);
future2.addListener(listener);
Run Code Online (Sandbox Code Playgroud)

不太优雅,但应该可以完成工作。

或者,更优雅,但你需要强制转换:

ListenableFuture<List<Object>> composedFuture = 
    Futures.allAsList(future1, future2);
Run Code Online (Sandbox Code Playgroud)