Использование правильного ExecutorService для асинхронного выполнения задачи - PullRequest
0 голосов
/ 04 января 2019

При обработке задачи мне нужно обработать 2 подзадачи (в основном этапы), которые можно выполнить асинхронно .

Я создал Executors.newSingleThreadExecutor () и вызвал его для выполнения дважды. Поскольку это однопоточный пул, это означает, что вторая подзадача (т. Е. Шаг 5 в приведенном ниже коде) будет выполняться последовательно, т. Е. Только после завершения шага 3. Нужно ли создавать экземпляр Executors.newFixedThreadExecutor (2) - с аргументом 2 в качестве аргумента, поскольку мне нужно выполнить только два шага асинхронно или что еще нужно сделать.

public class MyTaskImpl
{
private static final ExecutorService JOB_EXEC_SVC = Executors.newSingleThreadExecutor();

public void doTask() throws Exception
    {
      // step 1
      // step 2
      // step 3 execute ASYNC
JOB_EXEC_SVC.execute(() -> step3(param1, param2));
      // step 4
      // step 5 execute ASYNC
JOB_EXEC_SVC.execute(() -> step5(param));
      // step 6
    }
}

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Вы правы. Потому что вы используете один поток, так что этот поток является общим для обеих задач. Это означает, что эти две задачи будут выполняться асинхронно, но они будут выполняться последовательно, то есть шаг 5 будет выполняться после шага 3. Если вы хотите, чтобы шаг 3 и шаг 5 выполнялись между тем, Executors.newFixedThreadExecutor (2) полезен для этого. Вы можете использовать Executors.newCachedThreadPool () для большей производительности.

0 голосов
/ 04 января 2019

Вы правы. Поскольку ExecutorService, который вы используете, был создан с использованием newSingleThreadExecutor, шаг 5 будет выполнен после завершения шага 3. Чтобы выполнить два действия асинхронно, используйте newFixedThreadExecutor:

public class MyTaskImpl {

    private static final ExecutorService JOB_EXEC_SVC = Executors.newFixedThreadExecutor(2);

    public void doTask() throws Exception {
        // Step 1
        // Step 2
        // Step 3 (below)
        JOB_EXEC_SVC.execute(() -> step3(param1, param2));
        // Step 4
        // Step 5 (below)
        JOB_EXEC_SVC.execute(() -> step5(param));
    }
}

Это, однако, не гарантирует, что шаг 3 и шаг 5 будут выполняться параллельно. Например, если выполнение шага 4 занимает много времени, шаг 5 может быть передан в ExecutorService (т.е. вызывается execute) после того, как шаг 3 уже завершил выполнение.

Это также верно для однопоточного случая, но независимо от времени, которое занимает шаг 4, шаг 5 всегда будет выполняться после завершения шага 3 (но неясно, будет ли передан шаг 5, когда шаг 3 выполняется и блокируется пока шаг 3 не завершится или если шаг 5 будет отправлен после завершения шага 3).

...