面试题答案
一键面试import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureChainingExample {
public static void main(String[] args) {
CompletableFuture<String> userIdFuture = CompletableFuture.supplyAsync(() -> {
// 模拟从数据库查询用户ID
if (Math.random() < 0.5) {
throw new RuntimeException("数据库连接失败");
}
return "12345";
});
CompletableFuture<String> userInfoFuture = userIdFuture.thenCompose(userId ->
CompletableFuture.supplyAsync(() -> {
// 模拟根据用户ID查询用户详细信息
if (Math.random() < 0.5) {
throw new RuntimeException("数据库连接失败");
}
return "用户详细信息,ID: " + userId;
})
);
userInfoFuture.exceptionally(ex -> {
System.err.println("发生异常: " + ex.getMessage());
return "默认用户信息";
}).thenAccept(System.out::println);
try {
// 阻塞主线程等待结果
System.out.println(userInfoFuture.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
上述代码实现了链式异步操作:
CompletableFuture.supplyAsync
方法发起第一个异步任务,模拟从数据库查询用户ID,并且有一定概率抛出RuntimeException
模拟数据库连接失败。thenCompose
方法将第一个异步任务返回的用户ID作为参数,发起第二个异步任务,模拟根据用户ID查询用户详细信息,同样有一定概率抛出RuntimeException
模拟数据库连接失败。exceptionally
方法捕获整个链式操作过程中可能出现的异常,并打印错误信息,返回默认值。thenAccept
方法用于处理最终的结果并打印。get
方法用于阻塞主线程等待结果,在实际应用中,如果不希望主线程阻塞,可以省略这部分。