深入理解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/zh-hk/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

發表回復

登錄後才能評論