首页 > 其他分享 >springboot~CompletableFuture并行计算

springboot~CompletableFuture并行计算

时间:2024-05-06 13:44:46浏览次数:12  
标签:异步 return springboot 任务 并行计算 CompletableFuture sleep 方法

在Spring中,CompletableFuture通常用于异步编程,可以方便地处理异步任务的执行和结果处理,CompletableFuture 是 Java 8 引入的一个类,用于支持异步编程和并发操作。它基于 Future 和 CompletionStage 接口,提供了丰富的方法来处理异步任务的执行和结果处理。

下面是 CompletableFuture 实现的一些关键原理:

  1. 线程池支持CompletableFuture 内部使用线程池来执行异步任务,可以通过指定不同的线程池来控制任务的执行方式。默认情况下,CompletableFuture 使用 ForkJoinPool.commonPool() 作为默认的线程池。

  2. 回调函数CompletableFuture 支持链式调用,可以通过 thenApply(), thenAccept(), thenRun(), thenCompose() 等方法添加回调函数,在异步任务完成后处理任务的结果或执行下一步操作。

  3. 异常处理CompletableFuture 提供了 exceptionally(), handle(), whenComplete() 等方法来处理异步任务中可能抛出的异常,确保异常能够被捕获并处理。

  4. 组合操作CompletableFuture 支持多个 CompletableFuture 对象之间的组合操作,如 thenCombine(), thenCompose(), allOf(), anyOf() 等方法,实现并行执行、串行执行、等待所有任务完成等功能。

  5. CompletableFuture 工厂方法:除了 supplyAsync() 方法外,CompletableFuture 还提供了一系列工厂方法来创建 CompletableFuture 对象,如 runAsync(), completedFuture(), failedFuture() 等,方便快速创建并管理异步任务。

总的来说,CompletableFuture 的实现基于 Future 和 CompletionStage 接口,利用线程池、回调函数、异常处理、组合操作等机制,提供了强大而灵活的异步编程功能,使得开发人员能够更加方便地处理异步任务的执行和结果处理。

使用方法(一)链式

如果我们的业务方法已经写完了,这时可以直接通过supplyAsync方法来调用这些已知的方法,而不需要重新开发

CompletableFuture<String> a1 = CompletableFuture.supplyAsync(() -> {
      try {
          Thread.sleep(1000);
      } catch (InterruptedException e) {
          throw new RuntimeException(e);
      }
      return "Hello World";
  });
  CompletableFuture<String> a2 = CompletableFuture.supplyAsync(() -> {
      try {
          Thread.sleep(2000);
      } catch (InterruptedException e) {
          throw new RuntimeException(e);
      }
      return "Hello World";
  });
  CompletableFuture<String> a3 = CompletableFuture.supplyAsync(() -> {
      try {
          Thread.sleep(3000);
      } catch (InterruptedException e) {
          throw new RuntimeException(e);
      }
      return "Hello World";
  });

  // 这块最后是并行计算时间为3秒
  CompletableFuture.allOf(a1, a2, a3).join();

  String result = a1.get() + " | " + a2.get() + " | " + a3.get();

使用方法(二)独立方法

如果方法比较独立,并且之前没有开发过,那么你可以通过异步方法来将这些逻辑与调用代码解耦

@Service
@EnableAsync
public class ParallelTaskService {

    @Async
    public CompletableFuture<String> task1() {
        // 模拟一个耗时操作
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return CompletableFuture.completedFuture("Task 1 completed");
    }

    @Async
    public CompletableFuture<String> task2() {
        // 模拟另一个耗时操作
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return CompletableFuture.completedFuture("Task 2 completed");
    }
}

// 并行计算时,响应时间是2和3秒之中最大值,即3秒
@GetMapping("/hello-world2")
public CompletableFuture<String> helloWorld2() {
    CompletableFuture<String> task1Result = parallelTaskService.task1();
    CompletableFuture<String> task2Result = parallelTaskService.task2();

    // 等待所有任务都完成
    CompletableFuture<Void> allOf = CompletableFuture.allOf(task1Result, task2Result);

    // 处理所有任务完成后的逻辑
    return allOf.thenApply(voidResult -> {
        String result = task1Result.join() + " | " + task2Result.join();
        return result;
    });
}

标签:异步,return,springboot,任务,并行计算,CompletableFuture,sleep,方法
From: https://www.cnblogs.com/lori/p/18174868

相关文章

  • 3. SpringBoot 整合第三方技术
    1.整合Junit一般来说是不需要进行处理的,因为在创建SpringBoot工程时,会自动整合junit​的要说怎么配置的话?也可以写一下相关的配置:以下就是SpringBoot整合Junit相关步骤导入相关依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-b......
  • Camunda 整合SpringBoot基本Api
    代码实现:需要接口@AutowiredprivateRuntimeServiceruntimeService;@AutowiredprivateRepositoryServicerepositoryService;@AutowiredprivateTaskServicetaskService;发布流程:@GetMapping("/deploy")publicObjectdeploy(){......
  • SpringBoot3.1.5对应新版本SpringCloud开发(2)-Eureka的负载均衡
    Eureka的负载均衡负载均衡原理负载均衡流程老版本流程介绍当order-servic发起的请求进入Ribbon后会被LoadBalancerInterceptor负载均衡拦截器拦截,拦截器获取到请求中的服务名称,交给RibbonLoadBanlancerCient,然后RibbonLoadBanlancerCient会将服务名称当作服务id交给Dynamic......
  • 测试 springboot 项目苍穹外卖,解决 Unable to connect to Redis 错误问题
       使用IDEA启动springboot项目苍穹外卖后台项目sky-take-out,测试“菜品批量删除”接口时,能够正常完成操作,但是服务器始终显示下面错误信息:2024-05-0320:54:24.134ERROR24360---[nio-8181-exec-3]o.a.c.c.C.[.[.[/].[dispatcherServlet]  :Servlet.service()fo......
  • springboot为什么要用延迟导入?
    SpringBoot使用了多种方式来实现自动配置,其中DeferredImportSelector接口是这些机制之一。DeferredImportSelector是ImportSelector的一个扩展,它允许延迟导入配置类直到所有@Configuration类都被处理完毕。这对于某些自动配置类需要在应用程序上下文的创建过程中的后期阶段才能......
  • 解决创建SpringBoot工程加载较慢的问题
    设置ServerURL将https://start.spring.io改为https://start.aliyun.com如图所示:启动演示如图所示,启动成功......
  • SpringBoot3.1.5对应新版本SpringCloud开发(1)-Eureka注册中心
    服务的提供者和消费者服务之间可以通过Spring提供的RestTemplate来进行http请求去请求另一个Springboot的项目,这就叫做服务间的远程调用。当一个服务通过远程调用去调用另一个服务时,被调用的服务就叫做服务的提供者,调用服务的服务就叫做服务的消费者。一个服务可以既是服务的提......
  • springboot+MDCAdapter自定义starter实现日志全链路追踪
    MDCMDC(MappedDiagnosticContext,映射调试上下文)是日志系统提供的一种方便在多线程条件下记录日志的功能使用场景一个常用的场景就是Web服务器中给每个请求都分配一个独特的请求id,所有的日志都会打印这个请求id,这样一个请求下的所有日志信息都可以很方便的找到。欢迎关注个人公......
  • SpringBoot中分页插件PageHelper的使用
    SpringBoot如何使用PageHelper实现分页查询在原始的分页查询方法中,需要编写复杂的SQL语句来限制查询结果的范围,通常需要使用LIMIT或者ROWNUM等数据库特定的语法来实现分页。在每个需要分页的查询方法中,都需要手动计算分页的起始位置和偏移量,通常需要根据页码和每页数量来计算,这部......
  • [springboot]配置文件加载顺序
    一般项目直接使用.jar文件以server.port配置举例;以jar包内和jar包外说明内部和外部配置文件顺序由高到底,如下:外部-启动时指定参数外部-环境变量外部config/yml文件外部yml文件内部config/yml文件内部yml文件启动时,如果指定了激活的profile文件,会优先找激活的profile文......