CompletableFuture 使用示例

CompletableFuture 使用示例

CompletableFuture 是 Java 8 引入的异步编程工具,提供了强大的异步编程能力。以下是一些常见的使用示例:

1. 基本示例

1.1 创建简单的 CompletableFuture

java 复制代码
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class BasicExample {
    public static void main(String[] args) {
        // 创建一个已完成的 CompletableFuture
        CompletableFuture<String> completedFuture = CompletableFuture.completedFuture("Hello World");
        
        // 异步执行,不返回值
        CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
            System.out.println("异步任务执行中...");
        });
        
        // 异步执行,返回结果
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("计算任务执行中...");
            return "计算结果";
        });
        
        try {
            String result = future2.get(); // 阻塞获取结果
            System.out.println("获取结果: " + result);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}

1.2 链式操作

java 复制代码
import java.util.concurrent.CompletableFuture;

public class ChainExample {
    public static void main(String[] args) {
        CompletableFuture.supplyAsync(() -> {
                    System.out.println("第一步: 获取用户ID");
                    return 1001;
                })
                .thenApply(userId -> {
                    System.out.println("第二步: 根据用户ID获取用户名");
                    return "用户-" + userId;
                })
                .thenAccept(userName -> {
                    System.out.println("第三步: 打印用户名: " + userName);
                })
                .thenRun(() -> {
                    System.out.println("第四步: 所有操作完成");
                });
        
        // 等待异步任务完成
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

2. 组合多个 CompletableFuture

2.1 thenCompose - 顺序执行

java 复制代码
import java.util.concurrent.CompletableFuture;

public class ThenComposeExample {
    public static void main(String[] args) {
        CompletableFuture<String> future = getUserInfo(1001)
                .thenCompose(userInfo -> getOrderInfo(userInfo));
        
        future.thenAccept(orderInfo -> {
            System.out.println("最终结果: " + orderInfo);
        });
        
        // 等待任务完成
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    static CompletableFuture<String> getUserInfo(int userId) {
        return CompletableFuture.supplyAsync(() -> {
            System.out.println("获取用户信息,用户ID: " + userId);
            return "用户信息-" + userId;
        });
    }
    
    static CompletableFuture<String> getOrderInfo(String userInfo) {
        return CompletableFuture.supplyAsync(() -> {
            System.out.println("根据用户信息获取订单: " + userInfo);
            return "订单信息-" + userInfo;
        });
    }
}

2.2 thenCombine - 合并两个独立任务的结果

java 复制代码
import java.util.concurrent.CompletableFuture;

public class ThenCombineExample {
    public static void main(String[] args) {
        CompletableFuture<String> userFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("获取用户信息...");
            return "用户信息";
        });
        
        CompletableFuture<String> orderFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("获取订单信息...");
            return "订单信息";
        });
        
        // 合并两个结果
        userFuture.thenCombine(orderFuture, (userInfo, orderInfo) -> {
            System.out.println("合并用户和订单信息");
            return userInfo + " + " + orderInfo;
        }).thenAccept(result -> {
            System.out.println("合并结果: " + result);
        });
        
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

2.3 allOf - 等待所有任务完成

java 复制代码
import java.util.concurrent.CompletableFuture;
import java.util.Arrays;

public class AllOfExample {
    public static void main(String[] args) {
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            sleep(1000);
            return "任务1完成";
        });
        
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            sleep(2000);
            return "任务2完成";
        });
        
        CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
            sleep(1500);
            return "任务3完成";
        });
        
        CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2, future3);
        
        allFutures.thenRun(() -> {
            System.out.println("所有任务都已完成!");
            try {
                System.out.println("任务1结果: " + future1.get());
                System.out.println("任务2结果: " + future2.get());
                System.out.println("任务3结果: " + future3.get());
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    private static void sleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

2.4 anyOf - 等待任意一个任务完成

java 复制代码
import java.util.concurrent.CompletableFuture;

public class AnyOfExample {
    public static void main(String[] args) {
        CompletableFuture<String> fastTask = CompletableFuture.supplyAsync(() -> {
            sleep(500);
            return "快速任务完成";
        });
        
        CompletableFuture<String> slowTask = CompletableFuture.supplyAsync(() -> {
            sleep(2000);
            return "慢速任务完成";
        });
        
        CompletableFuture<Object> anyFuture = CompletableFuture.anyOf(fastTask, slowTask);
        
        anyFuture.thenAccept(result -> {
            System.out.println("第一个完成的任务结果: " + result);
        });
        
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    private static void sleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

3. 异常处理

3.1 exceptionally - 异常处理

java 复制代码
import java.util.concurrent.CompletableFuture;

public class ExceptionallyExample {
    public static void main(String[] args) {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            if (Math.random() > 0.5) {
                throw new RuntimeException("任务执行失败!");
            }
            return "任务执行成功";
        }).exceptionally(ex -> {
            System.err.println("发生异常: " + ex.getMessage());
            return "默认返回值";
        });
        
        future.thenAccept(result -> {
            System.out.println("最终结果: " + result);
        });
        
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

3.2 handle - 处理结果和异常

java 复制代码
import java.util.concurrent.CompletableFuture;

public class HandleExample {
    public static void main(String[] args) {
        CompletableFuture.supplyAsync(() -> {
                    if (Math.random() > 0.5) {
                        throw new RuntimeException("随机失败");
                    }
                    return "成功结果";
                })
                .handle((result, ex) -> {
                    if (ex != null) {
                        return "处理异常: " + ex.getMessage();
                    }
                    return "处理结果: " + result;
                })
                .thenAccept(System.out::println);
        
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

4. 实际应用示例

4.1 模拟订单处理流程

java 复制代码
import java.util.concurrent.CompletableFuture;
import java.util.Random;

public class OrderProcessingExample {
    public static void main(String[] args) {
        System.out.println("开始处理订单...");
        
        CompletableFuture<String> orderProcess = CompletableFuture
                // 验证订单
                .supplyAsync(() -> validateOrder("ORDER123"))
                .thenCompose(orderId -> {
                    // 验证成功后处理支付
                    return processPayment(orderId)
                            // 支付成功后发货
                            .thenCompose(paymentId -> shipOrder(paymentId))
                            // 发货后发送通知
                            .thenCompose(shipmentId -> sendNotification(shipmentId));
                })
                .exceptionally(ex -> {
                    // 处理整个流程中的异常
                    System.err.println("订单处理失败: " + ex.getMessage());
                    return "订单处理失败";
                });
        
        orderProcess.thenAccept(result -> {
            System.out.println("订单处理最终结果: " + result);
        });
        
        // 等待任务完成
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    static CompletableFuture<String> validateOrder(String orderId) {
        return CompletableFuture.supplyAsync(() -> {
            System.out.println("验证订单: " + orderId);
            sleep(500);
            if (new Random().nextDouble() < 0.1) {
                throw new RuntimeException("订单验证失败");
            }
            return orderId;
        });
    }
    
    static CompletableFuture<String> processPayment(String orderId) {
        return CompletableFuture.supplyAsync(() -> {
            System.out.println("处理支付,订单: " + orderId);
            sleep(800);
            if (new Random().nextDouble() < 0.1) {
                throw new RuntimeException("支付处理失败");
            }
            return "PAYMENT-" + orderId;
        });
    }
    
    static CompletableFuture<String> shipOrder(String paymentId) {
        return CompletableFuture.supplyAsync(() -> {
            System.out.println("发货,支付ID: " + paymentId);
            sleep(1000);
            if (new Random().nextDouble() < 0.1) {
                throw new RuntimeException("发货失败");
            }
            return "SHIPMENT-" + paymentId;
        });
    }
    
    static CompletableFuture<String> sendNotification(String shipmentId) {
        return CompletableFuture.supplyAsync(() -> {
            System.out.println("发送通知,发货ID: " + shipmentId);
            sleep(300);
            return "订单处理完成,发货ID: " + shipmentId;
        });
    }
    
    private static void sleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

4.2 并行调用多个服务

java 复制代码
import java.util.concurrent.CompletableFuture;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;

public class ParallelServiceCallExample {
    public static void main(String[] args) {
        // 并行调用多个服务
        CompletableFuture<Map<String, String>> userInfoFuture = 
            CompletableFuture.supplyAsync(() -> callUserService());
        
        CompletableFuture<List<String>> orderListFuture = 
            CompletableFuture.supplyAsync(() -> callOrderService());
        
        CompletableFuture<Double> inventoryFuture = 
            CompletableFuture.supplyAsync(() -> callInventoryService());
        
        // 合并所有结果
        CompletableFuture<Void> allData = CompletableFuture.allOf(
                userInfoFuture, orderListFuture, inventoryFuture);
        
        allData.thenRun(() -> {
            try {
                Map<String, String> userInfo = userInfoFuture.get();
                List<String> orders = orderListFuture.get();
                Double inventory = inventoryFuture.get();
                
                System.out.println("=== 所有服务调用完成 ===");
                System.out.println("用户信息: " + userInfo);
                System.out.println("订单列表: " + orders);
                System.out.println("库存数量: " + inventory);
                System.out.println("=== 开始业务处理 ===");
                
                // 处理业务逻辑
                processBusinessLogic(userInfo, orders, inventory);
                
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    static Map<String, String> callUserService() {
        System.out.println("调用用户服务...");
        sleep(1500);
        Map<String, String> userInfo = new HashMap<>();
        userInfo.put("name", "张三");
        userInfo.put("email", "zhangsan@example.com");
        userInfo.put("address", "北京市朝阳区");
        return userInfo;
    }
    
    static List<String> callOrderService() {
        System.out.println("调用订单服务...");
        sleep(1200);
        List<String> orders = new ArrayList<>();
        orders.add("订单-001");
        orders.add("订单-002");
        orders.add("订单-003");
        return orders;
    }
    
    static Double callInventoryService() {
        System.out.println("调用库存服务...");
        sleep(1000);
        return 150.5;
    }
    
    static void processBusinessLogic(Map<String, String> userInfo, 
                                    List<String> orders, 
                                    Double inventory) {
        System.out.println("处理业务逻辑...");
        // 模拟业务处理
        sleep(500);
        System.out.println("业务处理完成");
    }
    
    private static void sleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

5. 使用自定义线程池

java 复制代码
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CustomExecutorExample {
    public static void main(String[] args) {
        // 创建自定义线程池
        ExecutorService customExecutor = Executors.newFixedThreadPool(3);
        
        System.out.println("使用自定义线程池执行任务...");
        
        // 使用自定义线程池执行任务
        CompletableFuture<Void> future1 = CompletableFuture
                .runAsync(() -> task("任务1"), customExecutor);
        
        CompletableFuture<Void> future2 = CompletableFuture
                .runAsync(() -> task("任务2"), customExecutor);
        
        CompletableFuture<Void> future3 = CompletableFuture
                .runAsync(() -> task("任务3"), customExecutor);
        
        CompletableFuture<Void> allTasks = CompletableFuture.allOf(
                future1, future2, future3);
        
        allTasks.thenRun(() -> {
            System.out.println("所有任务完成");
            customExecutor.shutdown(); // 关闭线程池
        });
        
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    static void task(String name) {
        System.out.println(Thread.currentThread().getName() + " 执行: " + name);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        System.out.println(name + " 完成");
    }
}

总结

CompletableFuture 提供了丰富的 API 来处理异步编程:

  1. 创建方式supplyAsync(), runAsync()
  2. 链式操作thenApply(), thenAccept(), thenRun()
  3. 组合操作thenCompose(), thenCombine()
  4. 并行处理allOf(), anyOf()
  5. 异常处理exceptionally(), handle()

使用 CompletableFuture 可以优雅地处理复杂的异步编程场景,避免回调地狱,提高代码的可读性和可维护性。

相关推荐
一点技术1 小时前
基于SpringBoot的选课调查系统
java·spring boot·后端·选课调查系统
m0_686041612 小时前
C++中的适配器模式变体
开发语言·c++·算法
清风~徐~来2 小时前
【视频点播系统】WebSocketpp 介绍及使用
开发语言
爱吃大芒果2 小时前
Flutter for OpenHarmony 实战:mango_shop 路由系统的配置与页面跳转逻辑
开发语言·javascript·flutter
学***54232 小时前
如何轻松避免网络负载过大
开发语言·网络·php
RANCE_atttackkk2 小时前
Springboot+langchain4j的RAG检索增强生成
java·开发语言·spring boot·后端·spring·ai·ai编程
梵刹古音2 小时前
【C语言】 格式控制符与输入输出函数
c语言·开发语言·嵌入式
Acrelhuang2 小时前
工商业用电成本高?安科瑞液冷储能一体机一站式解供能难题-安科瑞黄安南
大数据·开发语言·人工智能·物联网·安全
hello 早上好2 小时前
03_JVM(Java Virtual Machine)的生命周期
java·开发语言·jvm