【发布时间】:2013-02-21 10:26:30
【问题描述】:
我正在寻找将ListenableFuture<Iterable<A>> 转换为单个ListenableFutures 序列的最佳方法。这是我正在寻找的方法签名:
public <A, B> Iterable<ListenableFuture<B>> splitAndRun(
final ListenableFuture<Iterable<A>> elements,
final Function<A, B> func,
final ListeningExecutorService executor
);
如果我返回 ListenableFuture<Iterable<ListenableFuture<B>>> 显然我可以这样做,但我觉得我应该能够拆分并运行它并保持它的异步性。
这是我目前的代码,但你会注意到结尾处的讨厌的.get(),这相当毁了事情。如果我的事情过于复杂,请原谅。
public class CallableFunction<I, O> implements Callable<O>{
private final I input;
private final Function<I, O> func;
public CallableFunction(I input, Function<I, O> func) {
this.input = input;
this.func = func;
}
@Override public O call() throws Exception {
return func.apply(input);
}
}
public <A, B> Iterable<ListenableFuture<B>> splitAndRun(
final ListenableFuture<Iterable<A>> elements,
final Function<A, B> func,
final ListeningExecutorService executor
) throws InterruptedException, ExecutionException {
return Futures.transform(elements,
new Function<Iterable<A>, Iterable<ListenableFuture<B>>>() {
@Override
public Iterable<ListenableFuture<B>> apply(Iterable<A> input) {
return Iterables.transform(input, new Function<A, ListenableFuture<B>>() {
@Override
public ListenableFuture<B> apply(A a) {
return executor.submit(new CallableFunction<A, B>(a, func));
}
});
}
}, executor).get();
}
【问题讨论】:
-
将 Chris Povirk 的第二个答案视为您问题的解决方案。通过一些调整,它只会导致单个
get等待合并的未来。使用 Mairbek Khadikov 的回答,您的代码中至少需要有 2 个gets。无论如何,为问题 +1。
标签: java asynchronous concurrency guava future