本文目录导读:

- 案例1:基础异步执行与结果获取
- 案例2:任务链式编排(thenApply / thenCompose)
- 案例3:两个独立任务的并行合并(thenCombine)
- 案例4:任务完成后的回调(thenAccept / whenComplete)
- 案例5:异常处理与恢复(exceptionally / handle)
- 案例6:超时控制(orTimeout / completeOnTimeout)
- 案例7:等待多个任务全部完成(allOf)
- 案例8:任意一个任务完成立即处理(anyOf)
- 案例9:手动完成 Future(complete / completeExceptionally)
案例1:基础异步执行与结果获取
场景:异步查询用户信息,并在主线程中阻塞等待结果。
import java.util.concurrent.CompletableFuture;
public class BasicExample {
public static void main(String[] args) throws Exception {
// 异步执行任务,返回 CompletableFuture
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
// 模拟耗时操作
try { Thread.sleep(2000); } catch (InterruptedException e) { }
return "用户数据";
});
// 阻塞获取结果(类似 Future.get())
String result = future.get();
System.out.println(result); // 输出:用户数据
}
}
说明:supplyAsync 将任务提交到 ForkJoinPool 线程池,get() 阻塞等待完成。
案例2:任务链式编排(thenApply / thenCompose)
场景:先查询用户ID,再根据ID查询用户详情。
public class ChainExample {
public static void main(String[] args) throws Exception {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
return "user123"; // 获取用户ID
}).thenApply(userId -> {
// 通过ID查询用户信息(同步或异步)
return "用户:" + userId + " 的详细信息";
}).thenApply(detail -> {
return detail + "(已格式化)";
});
System.out.println(future.get());
// 输出:用户:user123 的详细信息(已格式化)
}
}
说明:thenApply 将前一步的结果作为输入,同步执行转换,若需异步转换则用 thenCompose。
案例3:两个独立任务的并行合并(thenCombine)
场景:同时查询用户信息和订单信息,合并结果。
public class CombineExample {
public static void main(String[] args) throws Exception {
CompletableFuture<String> userFuture = CompletableFuture.supplyAsync(() -> {
return "用户信息";
});
CompletableFuture<String> orderFuture = CompletableFuture.supplyAsync(() -> {
return "订单信息";
});
// 两个任务完成后合并结果
CompletableFuture<String> combined = userFuture.thenCombine(orderFuture,
(user, order) -> user + " + " + order);
System.out.println(combined.get());
// 输出:用户信息 + 订单信息
}
}
说明:thenCombine 等待两个 Future 都完成,然后使用 BiFunction 合并。
案例4:任务完成后的回调(thenAccept / whenComplete)
场景:异步执行后,打印日志或更新UI,不返回新结果。
public class CallbackExample {
public static void main(String[] args) throws Exception {
CompletableFuture.supplyAsync(() -> {
return "任务结果";
}).thenAccept(result -> {
// 消费结果,无返回值
System.out.println("日志记录:" + result);
});
// 或者使用 whenComplete(无论成功/失败都会执行)
CompletableFuture.supplyAsync(() -> {
if (Math.random() > 0.5) throw new RuntimeException("出错");
return "成功";
}).whenComplete((result, ex) -> {
if (ex != null) {
System.out.println("出错了:" + ex.getMessage());
} else {
System.out.println("结果:" + result);
}
});
}
}
说明:thenAccept 只处理成功结果;whenComplete 同时处理成功和异常。
案例5:异常处理与恢复(exceptionally / handle)
场景:任务可能抛出异常,提供默认值或优雅降级。
public class ErrorHandlingExample {
public static void main(String[] args) throws Exception {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
if (true) throw new RuntimeException("数据库异常");
return "正常数据";
}).exceptionally(ex -> {
System.out.println("异常:" + ex.getMessage());
return "降级数据"; // 提供默认值
});
// 或者使用 handle(无论成功/失败都调用,可以转换结果)
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
return "正常";
}).handle((result, ex) -> {
if (ex != null) return "错误:" + ex.getMessage();
return "" + result;
});
System.out.println(future.get()); // 输出:降级数据
}
}
说明:exceptionally 只在异常时执行;handle 类似 finally,但可返回新结果。
案例6:超时控制(orTimeout / completeOnTimeout)
场景:防止任务长时间阻塞,指定超时时间。
import java.util.concurrent.TimeUnit;
public class TimeoutExample {
public static void main(String[] args) throws Exception {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(5000); } catch (InterruptedException e) { }
return "慢速数据";
}).orTimeout(2, TimeUnit.SECONDS); // 2秒超时则抛出 TimeoutException
// 或者用 completeOnTimeout 提供默认值
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(5000); } catch (InterruptedException e) { }
return "慢速数据";
}).completeOnTimeout("默认值", 2, TimeUnit.SECONDS);
System.out.println(future2.get()); // 2秒后输出:默认值
}
}
说明:Java 9+ 新增 orTimeout 和 completeOnTimeout,前者超时抛异常,后者返回默认值。
案例7:等待多个任务全部完成(allOf)
场景:批量查询多个服务,全部完成后汇总。
public class AllOfExample {
public static void main(String[] args) throws Exception {
CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> "A");
CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> "B");
CompletableFuture<String> task3 = CompletableFuture.supplyAsync(() -> "C");
// 等待所有任务完成
CompletableFuture<Void> allDone = CompletableFuture.allOf(task1, task2, task3);
// 阻塞直到全部完成
allDone.get();
// 单独获取每个结果
System.out.println(task1.get() + task2.get() + task3.get()); // 输出:ABC
}
}
说明:allOf 返回 CompletableFuture<Void>,需手动合并结果。
案例8:任意一个任务完成立即处理(anyOf)
场景:调用多个供应商,使用最先返回的结果(类似熔断降级)。
public class AnyOfExample {
public static void main(String[] args) throws Exception {
CompletableFuture<String> fastService = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(1000); } catch (InterruptedException e) { }
return "快速服务";
});
CompletableFuture<String> slowService = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(3000); } catch (InterruptedException e) { }
return "慢速服务";
});
// 任意一个完成即返回
CompletableFuture<Object> any = CompletableFuture.anyOf(fastService, slowService);
System.out.println(any.get()); // 输出:1秒后的"快速服务"
}
}
说明:anyOf 返回 Object 类型,实际是第一个完成的任务的结果。
案例9:手动完成 Future(complete / completeExceptionally)
场景:在回调或外部事件中主动设置结果。
public class ManualCompleteExample {
public static void main(String[] args) throws Exception {
CompletableFuture<String> future = new CompletableFuture<>();
// 模拟异步线程手动完成
new Thread(() -> {
try { Thread.sleep(2000); } catch (InterruptedException e) { }
future.complete("手动完成的数据"); // 手动设置结果
}).start();
System.out.println(future.get()); // 2秒后输出:手动完成的数据
}
}
说明:complete 设置成功结果,completeExceptionally 设置异常。
| 场景 | 方法 |
|---|---|
| 基础异步执行 | supplyAsync / runAsync |
| 链式转换(同步) | thenApply |
| 链式转换(异步) | thenCompose |
| 并行合并两个任务 | thenCombine |
| 结果消费 / 回调 | thenAccept / whenComplete |
| 异常处理 | exceptionally / handle |
| 超时控制 | orTimeout / completeOnTimeout |
| 等待所有任务完成 | allOf |
| 任意一个任务完成 | anyOf |
| 手动完成 Future | complete / completeExceptionally |
这些案例覆盖了日常开发中 90% 以上的异步编排需求。