我想知道使用ListenableFuture+addCallback()
代替的好处是什么invokeAll()
,以防我只对一次获得所有任务的结果感兴趣。
是否invokeAll()
隐藏任何抛出的异常?如果我使用invokeAll()
, asaddCallback()
提供onSuccess()
和onFailure()
方法但没有这样的功能,我是否需要处理其他任何事情invokeAll()
。
提前致谢!
我想知道使用ListenableFuture+addCallback()
代替的好处是什么invokeAll()
,以防我只对一次获得所有任务的结果感兴趣。
是否invokeAll()
隐藏任何抛出的异常?如果我使用invokeAll()
, asaddCallback()
提供onSuccess()
和onFailure()
方法但没有这样的功能,我是否需要处理其他任何事情invokeAll()
。
提前致谢!
使用ListenableFuture
,您可以提交任意数量的任务,然后将ListenableFuture
这些任务中的 s 传递给Futures.allAsList
,获得另一个ListenableFuture
将在所有任务完成后完成的任务。还有Futures.successfulAsList
, 即使某些任务失败,它也会成功,并null
为每个失败的任务提供结果。
然后,您可以阻塞当前线程以等待这些结果(使用 normal Future.get()
),或者如果您不想/不需要阻塞当前线程,您可以添加一个侦听器/回调以在它们完成时调用。
例子:
ListeningExecutorService executor = ...
List<Callable<Foo>> tasks = ...
List<ListenableFuture<Foo>> futures = Lists.newArrayList();
for (Callable<Foo> task : tasks) {
futures.add(executor.submit(task));
}
final ListenableFuture<List<Foo>> resultsFuture
= Futures.allAsList(futures);
// block until all tasks are done
List<Foo> results = resultsFuture.get();
// or add a callback to get called when the tasks complete
Futures.addCallback(resultsFuture, new FutureCallback<List<Foo>>() {
@Override public void onSuccess(List<Foo> results) {
// ...
}
@Override public void onFailure(Throwable throwable) {
// ...
}
}, someExecutor);
ExecutorService.invokeAll()
返回列表Futures<?>
然后您可以遍历此列表并执行future.get()
,如果在计算期间发生异常,则将抛出异常,如果没有发生错误则返回结果。
这里的例子:
class SecondFailTask implements Callable<Integer> {
private static volatile int counter = 0;
@Override
public Integer call() throws Exception {
counter++;
if (counter == 2){
throw new RuntimeException("Fail");
} else {
return counter;
}
}
public static void main(String[] args) throws Exception{
ExecutorService e = Executors.newSingleThreadExecutor();
List<SecondFailTask> tasks = Arrays.asList(new SecondFailTask(),new SecondFailTask(),new SecondFailTask());
List<Future<Integer>> futures = e.invokeAll(tasks);
for (Future<Integer> future : futures){
try {
System.out.println("Counter is " + future.get());
}catch (ExecutionException ex){
System.out.println(ex.getCause());
}
}
}
输出是:
Counter is 1
java.lang.RuntimeException: Fail
Counter is 3
我不确定是否有一种方法可以一次获取所有任务的结果,据我所知onSuccess()
或onFailure()
在每次任务计算后执行,并且以这种方式收集结果将是技巧(使用一些全局变量)。我更喜欢使用ExecutorService.invokeAll()
,但我不是番石榴专家,我可能会错过一些东西。