ExecutorService vs CompletableFuture

我一直在尝试实现一个异步过程,其中父方法调用一个子方法,该子方法将依次调用三个不同的方法。我希望所有这些过程都是异步完成的,即在并行进行子方法中的这三个调用之后,控件应返回到父方法并继续其其余执行。

我有这个代码,当测试工作时工作正常。

public ReturnSomething parent(){
    child();
    ...//rest to UI
}

private void child(){
  ExecutorService executorService = Executors.newFixedThreadPool(3);

  Runnable service1 = () -> {
     MyFileService.service1();
  };

  Runnable service2 = () -> {
      MyFileService.service2();
  };

  Runnable service3 = () -> {
      MyFileService.service3();
  };

  executorService.submit(service1);
  executorService.submit(service2);
  executorService.submit(service3);
}

现在,我的领导要求我使用它。

public ReturnSomething parent(){
    child();
    ...//rest to UI
}

private void child(){
    CompletableFuture.supplyAsync(() ->  MyFileService.service1();
    CompletableFuture.supplyAsync(() ->  MyFileService.service2();
    CompletableFuture.supplyAsync(() ->  MyFileService.service3();
}

我知道CompletableFuture是Java 8的新功能,但是第二个代码如何比第1个更好?由于对于 ExecutorService,我不会调用 “get()” 方法,因此我不会等待 aysnc 响应。那么,有人可以解释一下有什么区别吗?


答案 1

从功能上讲,这两种方法或多或少是相同的:

  • 您提交您的任务以供执行;
  • 你不要等待结果。

然而,从技术上讲,存在一些微妙的区别:

  • 在第二种方法中,您没有指定执行程序,因此它将使用通用 .如果您不想要,则必须将执行器作为第二个参数传递;ForkJoinPoolsupplyAsync()
  • API 允许使用 等轻松链接更多调用。因此,它比简单返回的更灵活CompletableFuturethenApply()thenCompose()FutureExecutorService.submit();
  • 使用允许使用 从您的方法轻松返回未来。CompletableFuturechild()return CompletableFuture.allOf(the previously created futures)

关于可读性,这是一个偏好问题,但是如果你想要等效的代码,一旦你以类似的方式格式化它,这种方法可能会被认为可读性会降低一些。比较:CompletableFuture

executorService.submit(MyFileService::service1);
executorService.submit(MyFileService::service2);
executorService.submit(MyFileService::service3);

CompletableFuture.supplyAsync(MyFileService::service1, executorService);
CompletableFuture.supplyAsync(MyFileService::service2, executorService);
CompletableFuture.supplyAsync(MyFileService::service3, executorService);

答案 2

在这两种情况下,您都不会等待结果。

第二种方法的优点只是更少的样板。这就是好用之地。runAsync()supplyAsync()

但是,如果您实际上没有返回任何值,则应使用runAsync()

第二种方法还提供了,即使用.在第一种情况下也不存在。CompletableFuture.allOf()


推荐