我正在创建 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) {
//...
}
}
问题是:我有时返回的对象少于 15 个,而不是从 get(( 方法返回所有 15 个 MyResult 对象。有时 12 有时 10 有时甚至更少,有时全部 15。
我的印象是get()
方法是阻塞调用,并将等待所有 15 个线程返回各自的结果,但看起来我错过了其中的一些并继续前进。我做错了什么?我没有正确收集结果/等待结果吗?当从任何 MyProcessor 任务引发错误时,是否会发生这种情况?
这可能意味着您的某些工作出现了异常。 很难从你的代码中分辨出来,但你需要对ExecutionException
做一些事情,而不是捕获和忽略它。
当您提交的Callable
从 call()
方法引发RuntimeException
时,Future.get()
会引发ExecutionException
。 仅当该方法正常返回时,它才会返回您的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
,该也应该被捕获,而不仅仅是忽略。