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

时间:2019-01-04 15:09:31

标签: java asynchronous concurrency threadpool executorservice

在处理任务时,我必须处理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 :(得分:2)

您是正确的。由于您使用的ExecutorService是使用newSingleThreadExecutor创建的,因此第3步完成后,第5步将完成。为了异步执行这两个动作,请使用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需要很长时间才能完成,则在步骤3已经完成执行之后,可以将步骤5提交给ExecutorService(即,调用execute)。

对于单线程情况也是如此,但是无论步骤4花费的时间如何,步骤5总是在步骤3完成后执行(但是不确定在步骤3运行并提交时是否提交了步骤5)直到第3步完成,或者第3步完成后是否提交了第5步。)

答案 1 :(得分:0)

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