ExecutorService pool=Executors.newFixedThreadPool(7);
List<Future<Hotel>> future=new ArrayList<Future<Hotel>>();
List<Callable<Hotel>> callList = new ArrayList<Callable<Hotel>>();
for(int i=0;i<=diff;i++){
String str="2013-"+(liDates.get(i).get(Calendar.MONTH)+1)+"-"+liDates.get(i).get(Calendar.DATE);
callList.add(new HotelCheapestFare(str));
}
future=pool.invokeAll(callList);
for(int i=0;i<=future.size();i++){
System.out.println("name is:"+future.get(i).get().getName());
}
Now I want pool to invokeAll
all the task before getting to the for loop but when I run this program for loop gets executed before that invokeAll
and throws this exception:
java.util.concurrent.ExecutionException: java.lang.NullPointerException at
java.util.concurrent.FutureTask$Sync.innerGet(Unknown Source) at
java.util.concurrent.FutureTask.get(Unknown Source) at
com.mmt.freedom.cheapestfare.TestHotel.main(TestHotel.java:65)
Caused by: java.lang.NullPointerException at
com.mmt.freedom.cheapestfare.HotelCheapestFare.getHotelCheapestFare(HotelCheapestFare.java:166)
at com.mmt.freedom.cheapestfare.HotelCheapestFare.call(HotelCheapestFare.java:219)
at com.mmt.freedom.cheapestfare.HotelCheapestFare.call(HotelCheapestFare.java:1)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) atjava.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run
invokeAll is a blocking method. It means – JVM won’t proceed to next line until all the threads are completed. So I think there is something wrong with your thread future result.
from this line I think there are some futures have no result and can be null, So you should check your code, if there are some Futures null,If so, get a if before this line executed.
The way an
ExecutorService
works is that when you callinvokeAll
it waits for all tasks to complete:What that means is that your tasks are all done but some may have thrown an exception. This exception is part of the
Future
- callingget
causes the exception to be rethrown wrapped in anExecutionException
.From you stacktrack
You can see that this is indeed the case. One of your tasks has failed with an NPE. The
ExecutorService
caught the exception and is telling you about it by throwing anExecutionException
when you callFuture.get
.Now, if you want to take tasks as they complete you need an
ExecutorCompletionService
. This acts as aBlockingQueue
that will allow you to poll for tasks as and when they finish.In this example I have one task that calls
take
on theExecutorCompletionService
which gets theFuture
s as they become available and then I submit tasks to theExecutorCompletionService
.This will allow you to get the failed task as soon as it fails rather than having to wait for all the tasks to either fail of succeed together.
The only complication is that it is difficult to tell the polling thread that all the tasks are done as everything is now asynchronous. In this instance I have used the knowledge that 100 tasks will be submitted so that it only need to poll 100 times. A more general way would be to collect the
Future
s from thesubmit
method as well and then loop over them to see if everything is completed.Future.get() throws below exceptions.
CancellationException
- if the computation was cancelledExecutionException
- if the computation threw an exceptionInterruptedException
- if the current thread was interrupted while waitingCatch all these exceptions when you call
get()
method.I have simulated divide by zero exception for some
Callable
tasks but exception in oneCallable
does not affect otherCallable
tasks submitted toExecutorService
if you catch above three exceptions as shown in example code.Example code snippet:
output: