当前位置: 首页 > 知识库问答 >
问题:

ExecutorService vs CompletableFuture

巢德华
2023-03-14

我一直在尝试实现一个异步过程,其中父方法调用一个子方法,而子方法又会调用三个不同的方法。我希望所有的过程都是异步完成的,也就是说,在子方法中的这三个调用并行进行之后,控件应该返回到父方法,并继续执行它的其余部分。

我有这段代码,经过测试后效果很好。

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();
}

我知道完全未来是从Java8开始的,但是第二个代码怎么会比第一个更好呢?因为,对于ExecutorService,我没有调用get()方法,所以我不会等待aysnc响应。那么,有人能解释一下有什么区别吗?

共有3个答案

昝存
2023-03-14

首先,后者提高了可读性。其次,我不确定您是否急于(以一般方式解释您的问题)每次parent()调用child()时都创建了ExecutorService的新实例。

除此之外,的未来也是完整的。SupplySync返回一种非常方便的方法来获取对公共共享池的引用,这将缓解您的生活,除非您想对池中的线程服务您的请求的方式进行特定的自定义。

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool.html#commonPool--

宇文嘉勋
2023-03-14

你不是在等待两种情况的结果。

第二种方法的优点是简单地减少了模板。这就是runAsync()supplyAsync()的好处。

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

第二种方法也提供了等待所有期货的能力CompletableFuture.allOf()。这在第一种情况下也不存在。

郎建章
2023-03-14

功能上讲,这两种方法大致相同:

  • 你提交你的任务执行;
  • 你不能等待结果。

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

  • 在第二种方法中,您没有指定执行器,因此它将使用公共ForkJoinPool。如果不想传递,则必须将executor作为supplyAsync()的第二个参数传递
  • CompletableFutureAPI允许使用thenApply()thencose()等轻松链接更多调用。因此,它比ExecutorService返回的简单Future更灵活。提交()
  • 使用CompletableFuture可以使用return CompletableFuture从child()方法轻松返回未来。allOf(以前创建的期货)

关于可读性,这是一个优先选择的问题,但是如果你想要相同的代码,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);

 类似资料:

相关问答

相关文章

相关阅读