Reputation: 1175
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?
Upvotes: 0
Views: 2929
Reputation: 116878
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 ExecutionException
other than catching and ignoring it.
Future.get()
throws ExecutionException
when the Callable
you submitted throws a RuntimeException
from the call()
method. It will only return your MyResult
if the method returns normally with return
. You can get the exception that was thrown by doing:
} 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());
}
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,
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 the get()
is interrupted then the get()
throws an InterruptedException
which also should be caught and not just ignored.
Upvotes: 6