CompletableFuture.supplyAsync 和 ExecutorService.submit 的区别

  1. 返回类型:

    • CompletableFuture.supplyAsync 返回一个 CompletableFuture,它允许你链式地组合多个异步操作,并提供更丰富的异步编程接口。
    • ExecutorService.submit 返回一个 Future,它相对简单,只能获取异步任务的结果。
  2. 异步编程接口:

    • CompletableFuture 提供了更强大的异步编程接口,例如 thenApplythenAcceptthenCompose 等,允许你在一个异步任务完成后执行另一个异步任务。
    • Future 的接口相对较简单,主要提供 get 方法用于获取异步任务的结果。
  3. 异常处理:

    • CompletableFuture 具有更灵活的异常处理机制,可以通过 exceptionally 方法捕获异步任务的异常。
    • Future 的异常处理相对较为有限。
  4. 依赖关系:

    • CompletableFuture 允许你构建多个异步任务之间的依赖关系,通过 thenApplythenCombine 等方法,可以在一个任务完成后执行下一个任务。
    • Future 需要通过 get 阻塞等待任务完成,无法方便地构建依赖关系。
  5. Executor 的选择:

    • CompletableFuture.supplyAsync 默认使用 ForkJoinPool 进行异步执行,也可以通过重载方法指定其他 Executor
    • ExecutorService.submit 需要显式传递一个 Executor
      // CompletableFuture 示例
      CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
          // 异步计算的逻辑
          return "Hello, CompletableFuture!";
      });
      
      // 在这里可以执行其他操作
      
      // 获取异步计算的结果
      String result = future.join();
      System.out.println(result);
      
      // ExecutorService.submit 示例
      ExecutorService executorService = Executors.newFixedThreadPool(5);
      
      Future<String> future = executorService.submit(() -> {
          // 异步计算的逻辑
          return "Hello, ExecutorService.submit!";
      });
      
      // 在这里可以执行其他操作
      
      // 获取异步计算的结果
      String result = future.get();
      System.out.println(result);
      
      // 记得关闭线程池
      executorService.shutdown();
      

      接下来给大家展示一个更通用的CompletableFuture.supplyAsync 的模版

      @Override
      public Map<Long, List<Integer>> queryTechIdsMapByDealProductIds(List<Long> productIds) {
          // 创建一个并发安全的 Map,用于存储查询结果,其中 key 为产品ID,value 为技师ID列表
          Map<Long, List<Integer>> techMap = Maps.newConcurrentMap();
      
          // 使用 Stream 对产品ID列表进行处理
          productIds.stream()
                  .filter(Objects::nonNull) // 过滤掉为空的产品ID
                  .map(productId -> {
                      // 使用 CompletableFuture 实现异步查询技师ID
                      return CompletableFuture.supplyAsync(() ->
                                      // 异步调用 queryShowTechnicianIdByGoods 方法,返回技师ID列表
                                      techGoodsBindService.queryShowTechnicianIdByGoods(productId.intValue(), TechGoodBindEnum.GROUP),
                              executorService) // 使用指定的 executorService 处理异步任务
                              .thenAccept(result -> techMap.put(productId, result)) // 将查询结果放入 techMap
                              .exceptionally(e -> {
                                  // 异常处理,记录错误日志
                                  log.error("queryTechIdsByDealProductId 异常, productId={}", productId, e);
                                  return null;
                              });
                  })
                  .collect(Collectors.toList()) // 收集 CompletableFuture 到列表中
                  .forEach(CompletableFuture::join); // 等待所有异步任务完成
      
          // 返回查询结果的 Map
          return techMap;
      }
      

      总体而言,CompletableFuture 提供了更强大和灵活的异步编程功能,适用于构建复杂的异步任务链。ExecutorService.submit 则是一个更底层和简单的异步执行方式,适用于基本的异步任务执行。选择取决于具体的需求和异步编程的复杂性。

  • 14
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值