ExecutorService 与 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 的新内容,但是第二个代码如何比第一个更好?因为对于 ExecutorService,我没有调用“get()”方法,所以我不会等待 aysnc 响应。那么,有人可以解释一下有什么区别吗?


米琪卡哇伊
浏览 240回答 3
3回答

达令说

在功能上,这两种方法或多或少是相同的:您提交任务以供执行;你不等结果。但是,从技术上讲,存在一些细微差别:在第二种方法中,您没有指定执行程序,因此它将使用通用的ForkJoinPool. supplyAsync()如果您不想要,则必须将 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);

郎朗坤

在这两种情况下,您都不会等待结果。第二种方法的优点是更少的样板文件。这就是runAsync()和supplyAsync()是不错的。但是如果你实际上没有返回任何值,你应该使用 runAsync()第二种方法还提供了等待所有期货的能力CompletableFuture.allOf()。这在第一个场景中也不存在。

慕妹3242003

如果您使用的是 executorservice,请不要忘记在 executor 上调用 shutdown()。您也可以使用 runAsync() 而不是 supplyAsync()。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java