Future.get()没有返回所有结果

时间:2012-07-30 17:40:04

标签: java multithreading executorservice future

我正在创建15个可调用任务,并提交它们:

List<Future<MyResult>> futures = new ArrayList<Future<MyResult>>();
List<MyResult> myResults = new ArrayList<MyResult>();

for(int i = 1; i <= 15; i++){
    Callable<MyResult> task = new MyProcessor(//parameters);
    Future<MyResult> future = executorService.submit(task);
    futures.add(future);//used to iterate over to call get() to collect results in next for loop
}

然后我收集了15个MyResult对象:

for(Future<MyResult> future : futures){
  try {
    MyResult myResult = future.get();
    processorResults.add(myResult);
    } catch (InterruptedException e) {
      //...
    } catch (ExecutionException e) {
      //...
    }
}

问题是:不是从get()方法返回所有15个MyResult对象,我有时会得到少于15个对象。有时12有时10有时甚至更小,有时甚至全15。

我的印象是get()方法是一个阻塞调用,并且会等待所有15个线程返回相应的结果,但看起来我错过了其中一些并继续前进。 我做错了什么?我没有收集结果/正确等待结果?当从任何MyProcessor任务抛出ERROR时会发生这种情况吗?

1 个答案:

答案 0 :(得分:6)

这可能意味着你的一些工作引发了异常。从你的代码中很难说出来,除了捕获和忽略它之外,你需要对ExecutionException做一些事情。

当您提交的Future.get()ExecutionException方法中抛出Callable时,

RuntimeException会引发call()。如果方法通过MyResult正常返回,它只会返回return。您可以通过执行以下操作获得异常:

} catch (ExecutionException e) {
    // account for the throw here, the original exception is in e.getCause()
    // log it, count it, or ...
    logger.error("Job threw exception: " + e.getCause());
}
  

我的印象是get()方法是一个阻塞调用,并且会等待所有15个线程返回各自的结果,

这是对的。当你调用future.get()时会阻塞,直到作业结束 - 通过抛出异常或返回。如果进入get()的线程被中断,那么get()会抛出InterruptedException,这也应该被捕获而不是被忽略。