ExecutorService выполняет runnable в последовательном порядке - PullRequest
0 голосов
/ 10 декабря 2018

Я использую службу executor с newSingleThreadExecutor для выполнения моей задачи Runnable в последовательном порядке, однако, похоже, что порядок последовательного выполнения не гарантируется, так как иногда задачи выполняются в случайном порядке.

executorService =  Executors.newSingleThreadExecutor();
executorService.submit(MyTask1);
executorService.submit(MyTask2);

MyTaskвыполняет некоторую асинхронную операцию и отправляет результат обратно в класс, из которого я выполняю задачу.

, хотя в документах говорится, что задачи newSingleThreadExecutor () должны выполняться последовательно, я не могу выяснить, что яЯ пропускаю здесь. Любая помощь будет оценена.

Спасибо

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

tl; dr

Если результаты, которые вы смотрите, поступают не по порядку, производятся асинхронно, то все в порядке.Асинхронная работа выполняется на отдельной временной шкале.По определению, асинхронная работа, запускаемая задачей № 1, может не завершиться до тех пор, пока все задачи 1, 2 и 3 не будут выполнены (например).

Асинхронный означает «не жди меня»

Вы упомянули:

MyTask выполняет некоторую асинхронную операцию

Асинхронное выполнение означает, что вызывающему коду не нужно ждать завершения асинхронной операции.

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

Служба исполнителя продолжает работу.Служба исполнителя выполняет вторую отправленную задачу.Между тем, запрошенная выше асинхронная работа может быть еще не выполнена.Возможно, асинхронная работа ожидает ресурса, такого как ожидание возврата вызова по сети, или асинхронная работа ожидает выполнения запроса к базе данных.Это, по определению асинхронного , не блокирует задачу, переданную исполнителю.Служба executor теперь выполняет 2-ю отправленную задачу и может быть третьей или четвертой, прежде чем, наконец, ваша асинхронная работа завершится.

diagram of a series of submitted tasks being executed sequentially along a timeline with separate async work being done in parallel along several tasks after being spawned from the first task

Функция, а не ошибка

Другими словами, функция, а не ошибка.ExecutorService, возвращаемый Executors.newSingleThreadExecutor(), выполнил свое обещание «Задачи гарантированно выполняются последовательно».Тот факт, что в качестве побочного продукта одна из этих задач приводит к асинхронной работе, не меняет тот факт, что представленные задачи действительно выполнялись в их последовательном порядке.

0 голосов
/ 10 декабря 2018

Поскольку порядок выполнения гарантированно является последовательным, вы, вероятно, не используете однопоточный исполнитель в коде, который вы фактически выполняете.

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

executorService.submit(() -> {MyTask1.run(); MyTask2.run();});
...