为了账号安全,请及时绑定邮箱和手机立即绑定

ExecutorService 与 CompletableFuture

ExecutorService 与 CompletableFuture

米琪卡哇伊 2021-09-15 16:40:01
我一直在尝试实现一个异步过程,其中父方法调用一个子方法,该子方法将依次调用三个不同的方法。我希望所有这些过程都异步完成,即在子方法中的这三个调用并行进行后,控件应该返回到父方法并继续执行其余部分。我有这段代码,经过测试可以正常工作。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 的新内容,但是第二个代码如何比第一个更好?因为对于 ExecutorService,我没有调用“get()”方法,所以我不会等待 aysnc 响应。那么,有人可以解释一下有什么区别吗?
查看完整描述

3 回答

?
达令说

TA贡献1821条经验 获得超6个赞

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

  • 您提交任务以供执行;

  • 你不等结果。

但是,从技术上讲,存在一些细微差别:

  • 在第二种方法中,您没有指定执行程序,因此它将使用通用的ForkJoinPoolsupplyAsync()如果您不想要,则必须将 executor 作为第二个参数传递;

  • CompletableFutureAPI允许容易地连锁更多的呼叫用thenApply()thenCompose()等,这是由此更灵活比简单的Future返回通过ExecutorService.submit();

  • UsingCompletableFuture允许child()使用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);


查看完整回答
反对 回复 2021-09-15
?
郎朗坤

TA贡献1921条经验 获得超9个赞

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

第二种方法的优点是更少的样板文件。这就是runAsync()supplyAsync()是不错的。

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

第二种方法还提供了等待所有期货的能力CompletableFuture.allOf()。这在第一个场景中也不存在。


查看完整回答
反对 回复 2021-09-15
?
慕妹3242003

TA贡献1824条经验 获得超6个赞

如果您使用的是 executorservice,请不要忘记在 executor 上调用 shutdown()。您也可以使用 runAsync() 而不是 supplyAsync()。


查看完整回答
反对 回复 2021-09-15
  • 3 回答
  • 0 关注
  • 239 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信