ExecutorService.submit () против ExecutorSerivce.invokeXyz () - PullRequest
0 голосов
/ 06 апреля 2020

ExecutorService содержит следующие методы:

  • invokeAll(Collection<? extends Callable<T>> tasks)
  • invokeAny(Collection<? extends Callable<T>> tasks)
  • submit(Callable<T> task)

I я запутался в использовании терминов submit против invoke. Означает ли это, что invokeXyz() методы вызывают эти задачи сразу же, как только это возможно из базового пула потоков, а submit() выполняет какое-то планирование поставленных задач.

В этом ответе говорится "если мы хотим дождаться завершения всех задач, которые были переданы в ExecutorService". Что здесь означает «ждать»?

1 Ответ

0 голосов
/ 06 апреля 2020

И invoke..(), и submit() выполнят свои задачи немедленно (при условии наличия потоков для запуска задач). Разница в том, что invoke...() будет ждать задач, запущенных в отдельных потоках, до конечного sh, прежде чем вернуть результат, тогда как submit() вернется немедленно, то есть выполненная задача все еще выполняется в другой thread.

Другими словами, объекты Future, возвращаемые из invokeAll(), гарантированно находятся в состоянии, где Future.isDone() == true. Future объект, возвращаемый из submit(), может находиться в состоянии, в котором Future.isDone() == false.

Мы можем легко продемонстрировать разницу во времени.

public static void main(String... args) throws InterruptedException {
    Callable<String> c1 = () -> { System.out.println("Hello "); return "Hello "; };
    Callable<String> c2 = () -> { System.out.println("World!"); return "World!"; };
    List<Callable<String>> callables = List.of(c1, c2);
    ExecutorService executor = Executors.newSingleThreadExecutor();

    System.out.println("Begin invokeAll...");
    List<Future<String>> allFutures = executor.invokeAll(callables);
    System.out.println("End invokeAll.\n");

    System.out.println("Begin submit...");
    List<Future<String>> submittedFutures = callables.stream().map(executor::submit).collect(toList());
    System.out.println("End submit.");
}

И в результате callables распечатать сообщение Hello World до завершения метода invokeAll(); но callables print Hello World после завершения метода submit().

/*
Begin invokeAll...
Hello
World!
End invokeAll.

Begin submit...
End submit.
Hello
World!
*/

Вы можете поиграть с этим кодом в IDE, добавив некоторое sleep() время в c1 или c2 и смотреть, как печатает терминал. Это должно убедить вас, что invoke...() действительно ждет, пока что-то произойдет, а submit() - нет.

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