使用正确的 ExecutorService 异步执行任务

Using right ExecutorService to execute task asynchronously

在处理一项任务时,我必须处理 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
    }
}

你是对的。由于您正在使用的 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步可能会在第3步执行完毕后提交给ExecutorService(即调用execute)。

单线程情况下也是如此,但是无论第4步花费多少时间,第5步总是在第3步完成后执行(但不确定是否在第3步时提交第5步运行 并阻塞直到第 3 步完成,或者如果第 5 步在第 3 步完成后提交)。

你是对的。因为你使用单线程,所以那个线程是共享两个任务的。这意味着这两个任务将异步执行但它们将串行执行,即步骤 5 将在步骤 3 之后执行。如果您希望步骤 3 和步骤 5 同时执行,Executors.newFixedThreadExecutor(2) 对此很有用。您可以使用 Executors.newCachedThreadPool() 以获得更高的性能。