25
    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:6‌​5)

Caused by: java.lang.NullPointerException at 
com.mmt.freedom.cheapestfare.HotelCheapestFare.getHotelCheap‌estFare(HotelCheapes‌​tFare.java:166) 
at com.mmt.freedom.cheapestfare.HotelCheapestFare.call(HotelChe‌​apestFare.java:219)
at com.mmt.freedom.cheapestfare.HotelCheapestFare.call(HotelChe‌​apestFare.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(Unknow‌​n Source)
at java.lang.Thread.run
Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
  • InvokeAll should wait till all Callables have finished. Could you please add the exception and the stack trace? – jboi Aug 13 '13 at 06:54
  • internaly some thread goes to for loop before completion and throws exception –  Aug 13 '13 at 07:00
  • please help me i have to submit my task –  Aug 13 '13 at 07:07
  • According your stack trace: `com.mmt.freedom.cheapestfare.HotelCheapestFare.getHotelCheapestFare(HotelCheapes‌​tFare.java:166)`. Error should be there. – aim Aug 13 '13 at 07:09
  • i have a list at this point but when i debug it i am getting my list –  Aug 13 '13 at 07:25
  • what i thing is that some thread is accessing some other thread internally and its going to for loop before completion of pool.invoke() –  Aug 13 '13 at 07:28
  • You definitely must look at `HotelCheapes‌tFare.java`line 166 as @aim mentioned! It looks like you just access some object that is `null`. Nothing special about threads and tasks. – jboi Aug 13 '13 at 08:23

3 Answers3

21

The way an ExecutorService works is that when you call invokeAll it waits for all tasks to complete:

Executes the given tasks, returning a list of Futures holding their status and results when all complete. Future.isDone() is true for each element of the returned list. Note that a completed task could have terminated either normally or by throwing an exception. The results of this method are undefined if the given collection is modified while this operation is in progress.1(emphasis added)

What that means is that your tasks are all done but some may have thrown an exception. This exception is part of the Future - calling get causes the exception to be rethrown wrapped in an ExecutionException.

From you stacktrack

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 
                                ^^^ <-- from get

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 an ExecutionException when you call Future.get.

Now, if you want to take tasks as they complete you need an ExecutorCompletionService. This acts as a BlockingQueue that will allow you to poll for tasks as and when they finish.

public static void main(String[] args) throws Exception {
    final ExecutorService executorService = Executors.newFixedThreadPool(10);
    final ExecutorCompletionService<String> completionService = new ExecutorCompletionService<>(executorService);
    executorService.submit(new Runnable() {
        @Override
        public void run() {
            for (int i = 0; i < 100; ++i) {
                try {
                    final Future<String> myValue = completionService.take();
                    //do stuff with the Future
                    final String result = myValue.get();
                    System.out.println(result);
                } catch (InterruptedException ex) {
                    return;
                } catch (ExecutionException ex) {
                    System.err.println("TASK FAILED");
                }
            }
        }
    });
    for (int i = 0; i < 100; ++i) {
        completionService.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                if (Math.random() > 0.5) {
                    throw new RuntimeException("FAILED");
                }
                return "SUCCESS";
            }
        });
    }
    executorService.shutdown();
}

In this example I have one task that calls take on the ExecutorCompletionService which gets the Futures as they become available and then I submit tasks to the ExecutorCompletionService.

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 Futures from the submit method as well and then loop over them to see if everything is completed.

Boris the Spider
  • 59,842
  • 6
  • 106
  • 166
  • can i use ExecutorCompletionService with list of callable objects –  Aug 13 '13 at 08:49
  • @SahilKohli No, and that makes no sense. The reason you use a `Collection` in the `ExecutorService` is so that you can wait for **all** of them to finish before proceeding. With the ` ExecutorCompletionService` you are polling for completion so it makes no difference if you submit them all at once or in a loop. – Boris the Spider Aug 13 '13 at 08:59
  • my task is time consuming so i want them to run concurrently so that they all run at the same time and i get my future result after completion of threads –  Aug 13 '13 at 09:08
  • In that case you can use the `invokeAll` method of the `ExecutorService` and process all the `Future`s as you are currently doing. The reason to use an `ExecutorCompletionListener` is that you are notified as soon as each task is completed. These are two different things. I don't understand what you want; you can **either** process each result as it happens **or** process everything at the end. **In either case** you need to handle possible `ExecutionException`s. – Boris the Spider Aug 13 '13 at 10:14
  • yes I want forloop to only work after the completion of invokeall() but its working just after one or two threads gets completed so kindly tell me how to prevent my for loop so that it executes only after the completion of list. –  Aug 13 '13 at 10:22
  • @SahilKohli **NO IT IS NOT**. It runs after **all of your tasks have completed** as stated in the Javadoc. What is happening, as I explain above, is that one of your tasks is throwing an NPE from the `call` method and you are not handling the `ExecutionException` that is thrown from `Future.get`. – Boris the Spider Aug 13 '13 at 10:28
11

Future.get() throws below exceptions.

CancellationException - if the computation was cancelled

ExecutionException - if the computation threw an exception

InterruptedException - if the current thread was interrupted while waiting

Catch all these exceptions when you call get() method.

I have simulated divide by zero exception for some Callable tasks but exception in one Callable does not affect other Callable tasks submitted to ExecutorService if you catch above three exceptions as shown in example code.

Example code snippet:

import java.util.concurrent.*;
import java.util.*;

public class InvokeAllUsage{
    public InvokeAllUsage(){
        System.out.println("creating service");
        ExecutorService service = Executors.newFixedThreadPool(10);

        List<MyCallable> futureList = new ArrayList<MyCallable>();
        for ( int i=0; i<10; i++){
            MyCallable myCallable = new MyCallable((long)i+1);
            futureList.add(myCallable);
        }
        System.out.println("Start");
        try{
            List<Future<Long>> futures = service.invokeAll(futureList);  
            for(Future<Long> future : futures){
                try{
                    System.out.println("future.isDone = " + future.isDone());
                    System.out.println("future: call ="+future.get());
                }
                catch (CancellationException ce) {
                    ce.printStackTrace();
                } catch (ExecutionException ee) {
                    ee.printStackTrace();
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt(); // ignore/reset
                }
            }
        }catch(Exception err){
            err.printStackTrace();
        }
        System.out.println("Completed");
        service.shutdown();
    }
    public static void main(String args[]){
        InvokeAllUsage demo = new InvokeAllUsage();
    }
    class MyCallable implements Callable<Long>{
        Long id = 0L;
        public MyCallable(Long val){
            this.id = val;
        }
        public Long call(){

            if ( id % 5 == 0){
                id = id / 0;
            }           
            return id;
        }
    }
}

output:

creating service
Start
future.isDone = true
future: call =1
future.isDone = true
future: call =2
future.isDone = true
future: call =3
future.isDone = true
future: call =4
future.isDone = true
java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
        at InvokeAllUsage.<init>(InvokeAllUsage.java:20)
        at InvokeAllUsage.main(InvokeAllUsage.java:37)
Caused by: java.lang.ArithmeticException: / by zero
        at InvokeAllUsage$MyCallable.call(InvokeAllUsage.java:47)
        at InvokeAllUsage$MyCallable.call(InvokeAllUsage.java:39)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)
future.isDone = true
future: call =6
future.isDone = true
future: call =7
future.isDone = true
future: call =8
future.isDone = true
future: call =9
future.isDone = true
java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
        at InvokeAllUsage.<init>(InvokeAllUsage.java:20)
        at InvokeAllUsage.main(InvokeAllUsage.java:37)
Caused by: java.lang.ArithmeticException: / by zero
        at InvokeAllUsage$MyCallable.call(InvokeAllUsage.java:47)
        at InvokeAllUsage$MyCallable.call(InvokeAllUsage.java:39)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)
Completed
Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
  • Good explanation +1, so is it better to use service.invokeAll(futureList) or recursive with service.submit(new Runnable)? Is there any significant difference in time of execution between both method? Or is it just for different goals i.e return value? – Ivan Herlambang Apr 08 '19 at 11:19
  • When you need to wait for result of all tasks, use invokeAll. Otherwise you can use submit of task. – Ravindra babu Apr 09 '19 at 15:40
-1

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.

System.out.println("name is:"+future.get(i).get().getName());

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.

Winston
  • 1,202
  • 1
  • 13
  • 19
  • This is so wrong. Look at the stacktrace. The `Future.get` method is throwing an `ExectuionExcetion` - that is obvious. The result **is not** `null`. The `Callable` encountered a `NullPointerException` in the `call` method. This is caught in the `Future` and then wrapped in an `ExectionException`. – Boris the Spider Aug 13 '13 at 09:01
  • Sorry, I have missed the java.util.concurrent.ExecutionException, So It is the Future Code get this exception. – Winston Aug 13 '13 at 09:06
  • so some other better solution –  Aug 13 '13 at 09:11