深入理解SpringBoot CompletableFuture

一、基础概念

CompletableFuture是Java 8提供的一个类,用于处理异步任务的计算结果。

在Spring Boot中,我们可以使用CompletableFuture来实现异步调用,在处理并发请求的场景下提高系统性能。

CompletableFuture封装了异步执行的任务,我们可以通过一系列的方法链式调用来对任务的结果进行进一步的处理。

二、入门示例

下面我们通过一个简单的示例了解CompletableFuture的基本用法。

CompletableFuture.supplyAsync(() -> "hello world")
                 .thenAccept(result -> System.out.println(result));

这段代码实现了一个简单的异步调用,并打印出”hello world”。

在这段代码中,我们首先调用CompletableFuture的静态方法supplyAsync来创建一个CompletableFuture对象,其中传入的参数是一个Supplier类型的lambda表达式,用于异步执行一个任务,并返回计算结果。

接着,我们通过thenAccept方法链式调用接收处理结果,其中传入的参数是一个Consumer类型的lambda表达式,用于对计算结果进行进一步处理。

三、使用场景

CompletableFuture可以应用于很多场景,例如:

1.并发请求

当有大量请求需要处理时,使用CompletableFuture可以并发执行多个请求,提高系统性能。

CompletableFuture future1 = CompletableFuture.supplyAsync(() -> "hello");
CompletableFuture future2 = CompletableFuture.supplyAsync(() -> "world");

CompletableFuture result = CompletableFuture.allOf(future1, future2)
        .thenApply(v -> Stream.of(future1, future2)
                .map(CompletableFuture::join)
                .collect(Collectors.joining(" ")));

System.out.println(result.get());

在这段代码中,我们使用了CompletableFuture.allOf方法来并发执行两个请求,并通过thenApply方法处理两个请求的结果,最终输出结果为”hello world”。

2.异步IO

CompletableFuture还可以用于异步IO操作,例如读取文件、查询数据库等,可以有效地提高IO效率。

CompletableFuture.supplyAsync(() -> {
    try {
        return Files.readString(Paths.get("file.txt"));
    } catch (IOException e) {
        return null;
    }
}).thenAccept(result -> System.out.println(result));

在这段代码中,我们使用CompletableFuture来读取一个文件的内容,并异步地返回结果,最终通过thenAccept方法输出文件内容。

3.批处理

CompletableFuture还可以用于批处理操作,例如对多个数据进行计算、加工等。

List dataList = Arrays.asList("hello", "world", "java");

List<CompletableFuture> futures = dataList.stream()
        .map(data -> CompletableFuture.supplyAsync(() -> data.toUpperCase()))
        .collect(Collectors.toList());

CompletableFuture allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));

CompletableFuture<List> results = allFutures.thenApply(v -> futures.stream()
                .map(CompletableFuture::join)
                .collect(Collectors.toList()));

results.thenAccept(list -> System.out.println(list));

在这段代码中,我们使用CompletableFuture对多个数据进行批处理,并返回一组结果。

四、异常处理

在使用CompletableFuture时,我们也需要考虑到异常处理的问题。

对于异步执行的任务,如果出现异常,我们可以通过异常处理方法进行处理。

CompletableFuture.supplyAsync(() -> {
    throw new RuntimeException("error");
}).exceptionally(ex -> "error handled")
  .thenAccept(result -> System.out.println(result));

在这段代码中,我们通过异常处理方法exceptionally来捕获并处理异常,输出结果为”error handled”。

当然,我们也可以通过其他的方法来进行异常处理,例如handle方法、whenComplete方法等。

五、完整示例

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.IOException;

public class CompletableFutureDemo {

    public static void main(String[] args) throws Exception {
        // 示例1:简单异步调用
        CompletableFuture.supplyAsync(() -> "hello world")
                         .thenAccept(result -> System.out.println(result));

        // 示例2:并发请求
        CompletableFuture future1 = CompletableFuture.supplyAsync(() -> "hello");
        CompletableFuture future2 = CompletableFuture.supplyAsync(() -> "world");

        CompletableFuture result = CompletableFuture.allOf(future1, future2)
                .thenApply(v -> Stream.of(future1, future2)
                        .map(CompletableFuture::join)
                        .collect(Collectors.joining(" ")));

        System.out.println(result.get());

        // 示例3:异步IO操作
        CompletableFuture.supplyAsync(() -> {
            try {
                return Files.readString(Paths.get("file.txt"));
            } catch (IOException e) {
                return null;
            }
        }).thenAccept(result -> System.out.println(result));

        // 示例4:批处理操作
        List dataList = Arrays.asList("hello", "world", "java");

        List<CompletableFuture> futures = dataList.stream()
                .map(data -> CompletableFuture.supplyAsync(() -> data.toUpperCase()))
                .collect(Collectors.toList());

        CompletableFuture allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));

        CompletableFuture<List> results = allFutures.thenApply(v -> futures.stream()
                        .map(CompletableFuture::join)
                        .collect(Collectors.toList()));

        results.thenAccept(list -> System.out.println(list));

        // 示例5:异常处理
        CompletableFuture.supplyAsync(() -> {
            throw new RuntimeException("error");
        }).exceptionally(ex -> "error handled")
          .thenAccept(result -> System.out.println(result));
    }

}

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/278884.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-20 15:02
下一篇 2024-12-20 15:02

相关推荐

  • 从ga角度解读springboot

    springboot作为目前广受欢迎的Java开发框架,其中的ga机制在整个开发过程中起着至关重要的作用。 一、ga是什么 ga即Group Artifacts的缩写,它是Mave…

    编程 2025-04-29
  • CompletableFuture.supplyAsync() 方法 —— 实现并发编程

    CompletableFuture.supplyAsync() 方法是 Java8 发布的工具类之一,它可以让我们更好地实现异步编程和并发编程,提升程序的性能和效率。在本文中,我们…

    编程 2025-04-28
  • SpringBoot Get方式请求传参用法介绍

    本文将从以下多个方面对SpringBoot Get方式请求传参做详细的阐述,包括URL传参、路径传参、请求头传参、请求体传参等,帮助读者更加深入地了解Get请求方式下传参的相关知识…

    编程 2025-04-27
  • SpringBoot如何设置不输出Info日志

    本篇文章将带您了解如何在SpringBoot项目中关闭Info级别日志输出。 一、为什么要关闭Info日志 在开发中,我们经常会使用Log4j、Logback等框架来输出日志信息,…

    编程 2025-04-27
  • 深入解析Vue3 defineExpose

    Vue 3在开发过程中引入了新的API `defineExpose`。在以前的版本中,我们经常使用 `$attrs` 和` $listeners` 实现父组件与子组件之间的通信,但…

    编程 2025-04-25
  • 深入理解byte转int

    一、字节与比特 在讨论byte转int之前,我们需要了解字节和比特的概念。字节是计算机存储单位的一种,通常表示8个比特(bit),即1字节=8比特。比特是计算机中最小的数据单位,是…

    编程 2025-04-25
  • 深入理解Flutter StreamBuilder

    一、什么是Flutter StreamBuilder? Flutter StreamBuilder是Flutter框架中的一个内置小部件,它可以监测数据流(Stream)中数据的变…

    编程 2025-04-25
  • 解决springboot中scanBasePackages无法读取子包的问题

    在使用springboot搭建项目时,可能会遇到scanBasePackages无法读取子包的问题。本文将从几个方面详细阐述如何解决这个问题。 一、问题描述 在使用Springbo…

    编程 2025-04-25
  • 深入探讨OpenCV版本

    OpenCV是一个用于计算机视觉应用程序的开源库。它是由英特尔公司创建的,现已由Willow Garage管理。OpenCV旨在提供一个易于使用的计算机视觉和机器学习基础架构,以实…

    编程 2025-04-25
  • SpringBoot请求参数绑定

    解答:SpringBoot请求参数绑定是指将HTTP请求中的参数与Controller方法的参数绑定起来,使得参数的传递变得简单和方便。下面我们将从多个方面对SpringBoot请…

    编程 2025-04-25

发表回复

登录后才能评论