【问题标题】:How to wait for a list of Futures to complete如何等待期货列表完成
【发布时间】:2015-08-24 07:45:41
【问题描述】:

我有一个 Futures 列表,我希望在执行下一步之前完成所有任务。目前我正在这样做:

public static int[] benchmark(){

    List<Future<Integer>> futureNumbers = service.invokeAll(callableList);
    int[] numbers = new int[events.size()];
    int i = 0;

    for (Future<Integer> future : futureNumbers) {
        numbers[i] = future.get();
    }

    return numbers;
}

但是只有我返回的数组的第一个值是正确的,其他都是 0。我怎样才能实现 numbers 在每个任务完成后才返回?

您的帮助将不胜感激。

【问题讨论】:

  • 只是一个列表。不重要。
  • 为什么不重要?如果它的大小与futureNumbers 不同,则非常相关。
  • 大小是对的,但是除了第一个之外的所有值都是0。所以其他索引都是“空”的,没有用未来的值填充。
  • 我没有看到 i++,你总是写到 [0] 位置...
  • 呃……漫长的一天。谢谢。那是不必要的。

标签: java multithreading


【解决方案1】:

根据 invokeAll() 方法的 Java 规范,List&lt;Future&lt;T&gt;&gt; 将包含所有任务的结果,并且只有当所有线程正常或由于异常完成时,您才会得到 Future
所以,你的 Future 对象应该有所有的结果。

执行给定的任务,返回持有它们的 Futures 列表 全部完成后的状态和结果。

可能性:

  1. 可能发生的情况是您的某些线程由于异常而中止,因此 call() 方法无法返回所需的结果。此外,由于它是一个新的执行线程,您不会看到传播的异常。
    因此,为了应对/管理这个问题,请将所有 call() 方法的代码包含在 try-catch 中,并从 catch 中打印堆栈跟踪。你会知道是否有一些例外。
  2. 另一种可能性是您的某些 Callable 实现没有返回任何内容,并且可能只是无效的,因此您在 Future 对象中没有得到任何内容。

验证步骤:
isDone() - 如果此任务完成,则返回 true。完成可能是由于正常终止、异常或取消 - 在所有这些情况下,此方法都将返回 true。

for (Future<Integer> future : futureNumbers) {
      System.out.println(future.isDone());  
      numbers[i] = future.get();
}

【讨论】:

    猜你喜欢
    • 2013-06-29
    • 2020-10-31
    • 2019-08-12
    • 2013-06-30
    • 2015-06-03
    • 1970-01-01
    • 1970-01-01
    • 2020-06-12
    • 2021-01-23
    相关资源
    最近更新 更多