Java invokeAll()与番石榴上市的未来+;addCallback()

Java invokeAll()与番石榴上市的未来+;addCallback(),java,multithreading,concurrency,threadpool,guava,Java,Multithreading,Concurrency,Threadpool,Guava,我想知道使用ListenableFuture+addCallback()而不是invokeAll(),如果我只想一次获得所有任务的结果,有什么好处 invokeAll()是否隐藏抛出的任何异常?如果我正在使用invokeAll(),我还需要处理其他任何事情吗,因为addCallback()提供了onSuccess()和onFailure()方法,但是invokeAll()没有这样的功能 提前谢谢 ExecutorService.invokeAll()返回未来的列表,然后您可以迭代此列表并执行fu

我想知道使用
ListenableFuture+addCallback()
而不是
invokeAll()
,如果我只想一次获得所有任务的结果,有什么好处

invokeAll()
是否隐藏抛出的任何异常?如果我正在使用
invokeAll()
,我还需要处理其他任何事情吗,因为
addCallback()
提供了
onSuccess()
onFailure()
方法,但是
invokeAll()
没有这样的功能


提前谢谢

ExecutorService.invokeAll()
返回
未来的列表
,然后您可以迭代此列表并执行
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());
            }
        }
    }

据我所知,我不确定是否有一种方法可以一次获取所有任务的结果
onSuccess()
onFailure()
在每次任务计算后执行,这样收集结果将是一个技巧(使用一些全局变量)。我更喜欢使用
ExecutorService.invokeAll()
,但我不是番石榴专家,我可能会错过一些东西。

ExecutorService.invokeAll()
返回
未来的列表
,然后您可以遍历此列表并执行
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());
            }
        }
    }

据我所知,我不确定是否有一种方法可以一次获取所有任务的结果
onSuccess()
onFailure()
在每次任务计算后执行,这样收集结果将是一个技巧(使用一些全局变量)。我更喜欢使用
ExecutorService.invokeAll()
,但我不是番石榴专家,我可能会错过一些东西。

使用
ListenableFuture
,您可以提交任意数量的任务,然后将这些任务中的
ListenableFuture
传递给,正在获取另一个
ListenableFuture
,它将在所有任务完成后完成。还有,即使某些任务失败,它也会成功,并为每个失败的任务提供
null
结果

然后,您可以阻塞当前线程以等待这些结果(使用普通的
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);
ListingExecutor服务执行器=。。。
列出任务=。。。
List futures=Lists.newArrayList();
for(可调用任务:任务){
添加(执行者提交(任务));
}
最终列出的未来结果未来
=期货。allAsList(期货);
//阻止,直到所有任务完成
List results=resultsFuture.get();
//或者添加回调以在任务完成时调用
Futures.addCallback(resultsFuture,newfutureCallback(){
@成功时覆盖公共无效(列出结果){
// ...
}
@失效时覆盖公共无效(可丢弃){
// ...
}
}(执行人);

使用
ListenableFuture
,您可以提交任意数量的任务,然后将这些任务中的
ListenableFuture
传递到,获得另一个
ListenableFuture
,该任务将在所有任务完成后完成。还有,即使某些任务失败,它也会成功,并为每个失败的任务提供
null
结果

然后,您可以阻塞当前线程以等待这些结果(使用普通的
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);
ListingExecutor服务执行器=。。。
列出任务=。。。
List futures=Lists.newArrayList();
for(可调用任务:任务){
添加(执行者提交(任务));
}
最终列出的未来结果未来
=期货。allAsList(期货);
//阻止,直到所有任务完成
List results=resultsFuture.get();
//或者添加回调以在任务完成时调用
Futures.addCallback(resultsFuture,newfutureCallback(){
@成功时覆盖公共无效(列出结果){
// ...
}
@失效时覆盖公共无效(可丢弃){
// ...
}
}(执行人);

谁强迫你使用
未来列表
?不,on是强迫我,我的问题是出于兴趣,想知道我是否遗漏了什么。谁强迫你使用未来列表?不,on是强迫我,我的问题是出于兴趣,想知道我是否遗漏了什么。你能给我指一些代码吗?当然我可以用谷歌搜索,但是当我之前尝试的时候,没有得到任何相关的代码。@Tingya:添加了一个例子。谢谢!这现在更有意义了@科林德:我对番石榴也有疑问。如果可能的话,你能回顾一下我的设计,帮我澄清我的一些疑问,以及我应该如何处理这些疑问吗?我最近开始与番石榴ListenableFuture合作,我很喜欢,但对如何有效地使用它们有些困惑。@ColinD嘿,你是来聊天的吗。这将有助于我了解如何正确使用番石榴酱。我试图在我的库中实现同步和异步实现,所以我使用Guava提供的future,但需要一些建议。我会在这里。如果可能的话,你什么时候有空都可以加入。你能给我指一些代码吗?当然我可以用谷歌搜索,但是当我之前尝试的时候,没有得到任何相关的代码。@Tingya:添加了一个例子。谢谢!这现在更有意义了@科林德:我对番石榴也有疑问。如果可能的话,你能回顾一下我的设计,帮我澄清我的一些疑问,以及我应该如何处理这些疑问吗?我最近开始与番石榴ListenableFuture合作,我很喜欢,但对如何有效地使用它们有些困惑。@ColinD嘿,你是来聊天的吗。它是w