我正在创建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时会发生这种情况吗?
答案 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
,这也应该被捕获而不是被忽略。