Вызывает ли invokeAll () основной поток? - PullRequest
2 голосов
/ 02 июля 2019

Мне интересно, ждет ли основной поток завершения всех задач в параметре invokeAll (), прежде чем продолжить. Вот мой код, и кажется, что это так.

public static void main(String[] args) throws InterruptedException {

    ExecutorService service = null;
    try
    {
        service = Executors.newCachedThreadPool();
        List<Callable<?>> list = new ArrayList<>();
        for(int i = 0; i < 1000; i++)
        {
            list.add(() -> {System.out.println("Not yet"); return null;});
        }
        service.invokeAll(list);
        System.out.println("END!"); // Output "END" at last no matter what
    }
    finally
    {
        if(service != null)
        {
            service.shutdown();
        }
    }
}

Как видите, независимо от того, сколько задач я создал, будь то 1000 или 10000, программа все равно выдаст «END» в конце.

Может кто-нибудь подтвердить эту информацию? Большое вам спасибо!

Ответы [ 2 ]

4 голосов
/ 02 июля 2019

Это то, что javadoc для invokeAll(...) говорит (мой комментарий вставлен):

Выполняет заданные задачи, возвращая список Фьючерсов с их статусом и результатами, когда все выполнено.

Примечание: "когда все завершено" ... не раньше.

Future.isDone() верно для каждого элемента возвращаемого списка.

Это означает, что задачи выполнены.

Обратите внимание, что завершенная задача могла быть завершена либо нормально, либо с помощью исключения. Результаты этого метода не определены, если данная коллекция была изменена во время выполнения этой операции.

Параметры: задачи - сборник задач

Возвращает: список Futures, представляющий задачи, в том же последовательном порядке, что итератор для заданного списка задач, каждая из которых завершена.

Еще раз ... он говорит, что задачи завершены .


Короче говоря, трижды раза говорится, что задачи завершены до того, как invokeAll() вернется.

4 голосов
/ 02 июля 2019

В документации ExecutorService.invokeAll() указано (выделено мое):

Выполняет заданные задачи, возвращая список фьючерсов, содержащих их статус и результаты когда все завершено .

И документация класса ExecutorService подчеркивает этот пункт для каждого метода, предназначенного для запуска задач (выделено мое):

Методы invokeAny и invokeAll выполняют наиболее часто используемые формы массового выполнения, выполнения набора задач и затем ожидания по крайней мере один или все, чтобы завершить .

Как минимум один для invokeAny() и все для invokeAll().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...