InvokeAll () blocking call in java 7

ExecutorService executorService = Executors.newSingleThreadExecutor();

Set<Callable<String>> callables = new HashSet<Callable<String>>();

callables.add(new Callable<String>() {
    public String call() throws Exception {
        return "Task 1";
    }
});
callables.add(new Callable<String>() {
    public String call() throws Exception {
        return "Task 2";
    }
});
callables.add(new Callable<String>() {
    public String call() throws Exception {
        return "Task 3";
    }
});

List<Future<String>> futures = executorService.invokeAll(callables);

for(Future<String> future : futures){
    System.out.println("future.get = " + future.get());
}

      

For this piece of code. My question is "invokeAll () blocking call"? I mean, when the code ran on the invokeAll () line, did we mask there to wait for the whole result to be generated?

+3


source to share


2 answers


Performs the specified tasks, returning a list of futures containing their status and results when completed. Future.isDone () is true for every element of the returned list. Note that the completed task can have either ok or by throwing an exception. The result of this method is undefined if the given collection has been modified and this operation is in progress.

Futures can only be executed after execution is complete, so this method can only return after tasks have completed.

The fact that it can throw InterruptedException also indicates a blocking action.



Looking at the implementation invokeAll

at java.util.concurrent.AbstractExecutorService

(comment on line):

public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
    throws InterruptedException {
    if (tasks == null)
        throw new NullPointerException();
    ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
    boolean done = false;
    try {
        for (Callable<T> t : tasks) {
            RunnableFuture<T> f = newTaskFor(t);
            futures.add(f);
            execute(f);
        }
        for (int i = 0, size = futures.size(); i < size; i++) {
            Future<T> f = futures.get(i);
            if (!f.isDone()) {
                try {
                    f.get(); // <== *** BLOCKS HERE ***

                } catch (CancellationException ignore) {
                } catch (ExecutionException ignore) {
                }
            }
        }
        done = true;
        return futures;
    } finally {
        if (!done)
            for (int i = 0, size = futures.size(); i < size; i++)
                futures.get(i).cancel(true);
    }
}

      

In fact, looking at the referenced implementation is what you usually have to do in these cases where the Javadoc-Specese seems to be difficult to decipher. (given that some implementation details are not part of the specification.)

+5


source


Do you mean if the parent thread will wait for the entire thread created by your call ExecutorService

? Then the answer is yes, the parent thread will wait, and once all threads are finished, you will get a list of object Futures

that will contain the result of each execution of the thread.

See below ExecutorService.invokeAll ()



Performs the specified tasks, returning a list of futures containing their status and results when completed .

+1


source







All Articles