从ExecutorService.invokeAll获取结果列表

时间:2012-06-28 06:27:27

标签: java guava

我可能在Guava API中遗漏了一些东西。如何在没有强制转换的情况下将ExecutorService.invokeAll与Futures.allAsList一起使用?

我的用例是我想提交一个Callables列表并等待所有执行(并行)。我只对Callables的结果列表感兴趣。

    ListeningExecutorService executor = MoreExecutors.sameThreadExecutor(); //or any other ExecutorService
    List<Future<Object>> futures = 
        executor.invokeAll(singletonList(new Callable<Object>() {
            @Override public Object call() throws Exception {
                return 42;
            }
        }
    ));
    Iterable<ListenableFuture<Object>> listableFutures = 
        (Iterable<ListenableFuture<Object>>) (Iterable) futures;
    //would like to use "futures" here
    ListenableFuture<List<Object>> r = Futures.allAsList(listableFutures);
    System.out.println(r.get());

在一个完美的世界里,我想打电话给ListeningExecutorService.allAsList(Collection<? extends Callable<T>> tasks)并获得Future<List<T>>甚至List<T>

2 个答案:

答案 0 :(得分:0)

不。你应该做演员。由于Java限制覆盖方法的方式,这是无法避免的。

ListeningExecutorService.invokeAll州的Javadoc

  

返回列表中的所有元素都必须是ListenableFuture实例。

答案 1 :(得分:0)

由于不支持使用Futures.allAsList而不使用强制转换为Iterable<? extends ListenableFuture<? extends V>>,因此使用for循环的简单解决方案应该是最好的:

    ListeningExecutorService executor = MoreExecutors.sameThreadExecutor();
    List<Future<Object>> futures = executor.invokeAll(
        singletonList(new Callable<Object>() {
            @Override public Object call() throws Exception {
                return 42;
           }
        }
    ));
    List<Object> r = Lists.newArrayList();
    for (Future<Object> future : futures) r.add(future.get());