一、基礎概念
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-hant/n/278884.html