1. 背景
2. 代码实例
2.1 两个任务组合并排使用
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
simulateTask("加载用户数据");
return "用户小黑";
});
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
simulateTask("加载配置信息");
return "配置信息";
});
// 组合两个future,等待它们都完成
CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (user, config) -> {
return "处理结果: " + user + "," + config;
});
2.2 两个任务一起使用
小黑用supplyAsync启动了一个异步任务来查询数据库。然后用thenApply处理查询结果,用thenAccept消费处理后的结果,最后用thenRun标记所有操作完成。
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
simulateTask("查询数据库");
return "查询结果";
});
future.thenApply(result -> {
// 对结果进行处理
return "处理后的结果:" + result;
}).thenAccept(processedResult -> {
// 消费处理后的结果
System.out.println("最终结果:" + processedResult);
}).thenRun(() -> {
// 执行一些不需要前一个结果的操作
System.out.println("所有操作完成");
});
2.3 基本异常处理
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
if (new Random().nextBoolean()) {
throw new RuntimeException("出错啦!");
}
return "正常结果";
}).exceptionally(ex -> {
return "错误的回退结果:" + ex.getMessage();
});
future.thenAccept(System.out::println);
2.3 细粒度的异常处理
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
if (new Random().nextBoolean()) {
throw new RuntimeException("出错啦!");
}
return "正常结果";
}).handle((result, ex) -> {
if (ex != null) {
return "处理异常:" + ex.getMessage();
}
return "处理结果:" + result;
});
future.thenAccept(System.out::println);
2.4 两个任务并发然后再执行
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
simulateTask("加载用户信息");
return "用户小黑";
});
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
simulateTask("加载订单数据");
return "订单123";
});
CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (userInfo, orderInfo) -> {
return "合并结果:" + userInfo + "," + orderInfo;
});
combinedFuture.thenAccept(System.out::println);
2.4 管道式异常处理
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
// 第一个异步操作
return "第一步结果";
}).thenApply(result -> {
// 第二个异步操作,可能会出错
throw new RuntimeException("第二步出错啦!");
}).exceptionally(ex -> {
// 处理异常
return "在第二步捕获异常:" + ex.getMessage();
}).thenApply(result -> {
// 第三个异步操作
return "第三步使用结果:" + result;
});
future.thenAccept(System.out::println);
2.5 管道式异常处理
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
// 第一个异步操作
return "第一步结果";
}).thenApply(result -> {
// 第二个异步操作,可能会出错
throw new RuntimeException("第二步出错啦!");
}).exceptionally(ex -> {
// 处理异常
return "在第二步捕获异常:" + ex.getMessage();
}).thenApply(result -> {
// 第三个异步操作
return "第三步使用结果:" + result;
});
future.thenAccept(System.out::println);
2.6 如果你的一个异步操作依赖于另一个异步操作的结果,那么可以使用thenCompose方法。这个方法允许你在一个Future完成后,以其结果为基础启动另一个异步操作
CompletableFuture<String> masterFuture = CompletableFuture.supplyAsync(() -> {
simulateTask("获取主数据");
return "主数据结果";
});
CompletableFuture<String> dependentFuture = masterFuture.thenCompose(result -> {
return CompletableFuture.supplyAsync(() -> {
simulateTask("处理依赖于" + result + "的数据");
return "处理后的数据";
});
});
dependentFuture.thenAccept(System.out::println);