Java CompletableFuture
Java CompletableFuture
一、简介
CompletableFuture是 Java 8 引入的一个用于异步编程的工具类,它允许你以声明式的方式编写异步代码,并且可以方便地组合和处理多个异步操作的结果。
二、创建 CompletableFuture
-
使用
supplyAsync方法:supplyAsync接受一个Supplier<T>函数式接口作为参数,该接口的get方法会在异步执行时被调用,并返回一个结果。- 示例:
import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; public class CompletableFutureExample { public static void main(String[] args) throws ExecutionException, InterruptedException { CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { try { // 模拟耗时操作 Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return "Hello, CompletableFuture!"; }); // 获取异步操作的结果 String result = future.get(); System.out.println(result); } }
-
使用
runAsync方法:runAsync接受一个Runnable接口作为参数,用于执行一个没有返回值的异步操作。- 示例:
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> { try { Thread.sleep(2000); System.out.println("Asynchronous task completed."); } catch (InterruptedException e) { e.printStackTrace(); } }); future.get();
三、处理结果
-
thenApply方法:thenApply接受一个Function<T, R>函数式接口作为参数,该接口的apply方法会在异步操作完成后被调用,将上一个异步操作的结果作为输入,并返回一个新的结果。- 示例:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { return "Hello"; }); CompletableFuture<String> newFuture = future.thenApply(result -> { return result + ", World!"; }); System.out.println(newFuture.get());
-
thenAccept方法:thenAccept接受一个Consumer<T>函数式接口作为参数,该接口的accept方法会在异步操作完成后被调用,将上一个异步操作的结果作为输入,但没有返回值。- 示例:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { return "Hello"; }); future.thenAccept(result -> { System.out.println(result + ", World!"); }); future.get();
-
thenRun方法:thenRun接受一个Runnable接口作为参数,该接口的run方法会在异步操作完成后被调用,不接受上一个异步操作的结果作为输入。- 示例:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { return "Hello"; }); future.thenRun(() -> { System.out.println("Task completed."); }); future.get();
四、异常处理
-
exceptionally方法:exceptionally接受一个Function<Throwable, T>函数式接口作为参数,该接口的apply方法会在异步操作出现异常时被调用,并返回一个默认值或进行异常处理后的结果。- 示例:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { throw new RuntimeException("Something went wrong."); }); CompletableFuture<String> newFuture = future.exceptionally(ex -> { return "Default value"; }); System.out.println(newFuture.get());
-
handle方法:handle接受一个BiFunction<T, Throwable, R>函数式接口作为参数,该接口的apply方法会在异步操作完成或出现异常时被调用,接受上一个异步操作的结果(如果成功)或异常作为输入,并返回一个结果。- 示例:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { if (Math.random() < 0.5) { return "Success"; } else { throw new RuntimeException("Failure"); } }); CompletableFuture<String> newFuture = future.handle((result, ex) -> { if (ex!= null) { return "Error occurred: " + ex.getMessage(); } else { return result + " with handle."; } }); System.out.println(newFuture.get());
五、组合多个 CompletableFuture
-
thenCompose方法:- 用于将两个异步操作串联起来,当第一个异步操作完成后,将其结果作为参数传递给第二个异步操作的函数,并返回一个新的
CompletableFuture。 - 示例:
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> { return "Hello"; }); CompletableFuture<String> future2 = future1.thenCompose(result1 -> CompletableFuture.supplyAsync(() -> { return result1 + ", World!"; })); System.out.println(future2.get());
- 用于将两个异步操作串联起来,当第一个异步操作完成后,将其结果作为参数传递给第二个异步操作的函数,并返回一个新的
-
thenCombine方法:- 用于组合两个独立的异步操作,当两个异步操作都完成后,将它们的结果作为参数传递给一个函数,并返回一个新的
CompletableFuture。 - 示例:
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> { return "Hello"; }); CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> { return "World!"; }); CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (result1, result2) -> { return result1 + ", " + result2; }); System.out.println(combinedFuture.get());
- 用于组合两个独立的异步操作,当两个异步操作都完成后,将它们的结果作为参数传递给一个函数,并返回一个新的
-
allOf和anyOf方法:allOf接受多个CompletableFuture作为参数,返回一个CompletableFuture<Void>,当所有的CompletableFuture都完成时,这个返回的CompletableFuture才完成。anyOf接受多个CompletableFuture作为参数,返回一个CompletableFuture<Object>,当其中任何一个CompletableFuture完成时,这个返回的CompletableFuture就完成,并返回第一个完成的CompletableFuture的结果。- 示例:
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return "Result 1"; }); CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return "Result 2"; }); CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2); allFutures.get(); System.out.println("All futures completed."); CompletableFuture<Object> anyFuture = CompletableFuture.anyOf(future1, future2); System.out.println("First completed future result: " + anyFuture.get());
六、应用场景
-
并发网络请求:
- 可以同时发起多个网络请求,并在所有请求完成后进行处理。
- 示例:
import java.util.concurrent.CompletableFuture; import java.net.URL; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; public class NetworkRequestsExample { public static CompletableFuture<String> fetchDataFromURL(String urlStr) { return CompletableFuture.supplyAsync(() -> { try { URL url = new URL(urlStr); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine())!= null) { response.append(line); } reader.close(); connection.disconnect(); return response.toString(); } catch (Exception e) { throw new RuntimeException(e); } }); } public static void main(String[] args) throws Exception { String url1 = "https://example.com/api/resource1"; String url2 = "https://example.com/api/resource2"; CompletableFuture<String> future1 = fetchDataFromURL(url1); CompletableFuture<String> future2 = fetchDataFromURL(url2); CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2); allFutures.get(); System.out.println(future1.get()); System.out.println(future2.get()); } }
-
数据库查询和处理:
- 可以异步查询数据库,并在查询结果上进行进一步的处理。
- 示例:
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.concurrent.CompletableFuture; public class DatabaseExample { public static CompletableFuture<Integer> queryDatabase() { return CompletableFuture.supplyAsync(() -> { try (Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "username", "password"); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("SELECT COUNT(*) FROM mytable")) { if (resultSet.next()) { return resultSet.getInt(1); } else { return 0; } } catch (SQLException e) { throw new RuntimeException(e); } }); } public static void main(String[] args) throws Exception { CompletableFuture<Integer> future = queryDatabase(); Integer result = future.get(); System.out.println("Number of rows in the table: " + result); } }

浙公网安备 33010602011771号