I am creating, say, 15 Callable tasks, and submitting them:
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
}
Then I am collecting the 15 MyResult objects:
for(Future<MyResult> future : futures){
try {
MyResult myResult = future.get();
processorResults.add(myResult);
} catch (InterruptedException e) {
//...
} catch (ExecutionException e) {
//...
}
}
Issue is: Instead of getting ALL 15 MyResult objects back from the get() method, I am sometimes getting less than 15 objects back. Sometime 12 sometimes 10 sometimes even lesser, and sometimes all 15.
I was under the impression that get() method is a blocking call and will wait for ALL 15 threads to get back with respective results, but looks like I miss a few of them and move ahead.
What is it that I am doing wrong? Am I not collecting the results/ waiting for the results correctly? Does this happen when an ERROR is thrown from any of the MyProcessor task?
It could mean that some of your jobs threw an exception. It is hard to tell from your code but you need to do something with
ExecutionExceptionother than catching and ignoring it.Future.get()throwsExecutionExceptionwhen theCallableyou submitted throws aRuntimeExceptionfrom thecall()method. It will only return yourMyResultif the method returns normally withreturn. You can get the exception that was thrown by doing:This is correct. When you call
future.get()that will block until the job either finishes — either by throwing an exception or returning. If the thread that is going theget()is interrupted then theget()throws anInterruptedExceptionwhich also should be caught and not just ignored.