Java并发28:CompletableFuture异步编程 - 优雅的异步处理
Future的局限性 Future<Integer> future = executor.submit(() -> { return compute(); }); Integer result = future.get(); // 阻塞等待 // 问题: // 1. 无法主动完成 // 2. 无法链式调用 // 3. 无法组合多个Future // 4. 无法异常处理回调 CompletableFuture核心API 1. 创建 // 无返回值 CompletableFuture<Void> future = CompletableFuture.runAsync(() -> { System.out.println("Running"); }); // 有返回值 CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> { return 42; }); // 指定线程池 CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> { return 42; }, executorService); 2. 回调 CompletableFuture.supplyAsync(() -> "Hello") .thenApply(s -> s + " World") // 转换 .thenAccept(System.out::println) // 消费 .thenRun(() -> System.out.println("Done")); // 运行 3. 异常处理 CompletableFuture.supplyAsync(() -> { throw new RuntimeException("Error"); }) .exceptionally(ex -> { System.err.println("Exception: " + ex.getMessage()); return "default"; // 默认值 }) .thenAccept(result -> System.out.println(result)); 4. 组合 CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10); CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 20); // 两个都完成 future1.thenCombine(future2, (a, b) -> a + b) .thenAccept(System.out::println); // 30 // 任一完成 future1.applyToEither(future2, x -> x * 2) .thenAccept(System.out::println); // 全部完成 CompletableFuture.allOf(future1, future2).join(); // 任一完成 CompletableFuture.anyOf(future1, future2).join(); 实战案例 案例1:异步查询聚合 public CompletableFuture<UserInfo> getUserInfo(Long userId) { CompletableFuture<User> userFuture = CompletableFuture.supplyAsync( () -> userService.getUser(userId)); CompletableFuture<List<Order>> ordersFuture = CompletableFuture.supplyAsync( () -> orderService.getOrders(userId)); CompletableFuture<Address> addressFuture = CompletableFuture.supplyAsync( () -> addressService.getAddress(userId)); return CompletableFuture.allOf(userFuture, ordersFuture, addressFuture) .thenApply(v -> { User user = userFuture.join(); List<Order> orders = ordersFuture.join(); Address address = addressFuture.join(); return new UserInfo(user, orders, address); }); } 案例2:超时控制 CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { sleep(5000); // 模拟耗时操作 return "result"; }); try { String result = future.get(3, TimeUnit.SECONDS); // 3秒超时 } catch (TimeoutException e) { future.cancel(true); // 超时取消 return "default"; } // JDK 9+:orTimeout future.orTimeout(3, TimeUnit.SECONDS) .exceptionally(ex -> "default"); 方法对比 方法 描述 是否阻塞 线程池 thenApply 转换结果 否 同当前 thenApplyAsync 转换结果 否 ForkJoinPool thenAccept 消费结果 否 同当前 thenRun 执行操作 否 同当前 thenCompose 链式异步 否 同当前 thenCombine 组合两个 否 同当前 get() 获取结果 是 - join() 获取结果 是 - 最佳实践 1. 指定线程池 ...