面试题答案
一键面试链式调用
在Java中,CompletableFuture
可以通过thenApply
、thenAccept
、thenRun
等方法实现链式调用。
thenApply
: 用于对前一个CompletableFuture
的结果进行转换,返回一个新的CompletableFuture
。
CompletableFuture.supplyAsync(() -> "Hello")
.thenApply(s -> s + ", World")
.thenApply(String::toUpperCase)
.thenAccept(System.out::println);
thenAccept
: 用于对前一个CompletableFuture
的结果进行消费,不返回新的结果。
CompletableFuture.supplyAsync(() -> "Hello")
.thenAccept(s -> System.out.println(s + ", World"));
thenRun
: 在前一个CompletableFuture
完成时执行一个无参数的任务。
CompletableFuture.supplyAsync(() -> "Hello")
.thenRun(() -> System.out.println("Task completed"));
并行执行
CompletableFuture
可以通过allOf
和anyOf
方法实现多个异步任务的并行执行。
allOf
: 等待所有CompletableFuture
都完成。
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Result1");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Result2");
CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2);
allFutures.thenRun(() -> {
try {
String result1 = future1.get();
String result2 = future2.get();
System.out.println(result1 + " " + result2);
} catch (Exception e) {
e.printStackTrace();
}
}).join();
anyOf
: 只要有一个CompletableFuture
完成,就返回。
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Result1";
});
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Result2");
CompletableFuture.anyOf(future1, future2)
.thenApply(Object::toString)
.thenAccept(System.out::println)
.join();
处理异常
CompletableFuture
提供了exceptionally
、handle
等方法来处理异常。
exceptionally
: 当CompletableFuture
发生异常时,返回一个默认值。
CompletableFuture.supplyAsync(() -> {
if (Math.random() < 0.5) {
throw new RuntimeException("Simulated exception");
}
return "Success";
})
.exceptionally(ex -> {
System.out.println("Caught exception: " + ex.getMessage());
return "Default value";
})
.thenAccept(System.out::println);
handle
: 可以同时处理正常结果和异常情况,返回一个新的结果。
CompletableFuture.supplyAsync(() -> {
if (Math.random() < 0.5) {
throw new RuntimeException("Simulated exception");
}
return "Success";
})
.handle((result, ex) -> {
if (ex != null) {
System.out.println("Caught exception: " + ex.getMessage());
return "Default value";
}
return result;
})
.thenAccept(System.out::println);
内部实现原理
- 异步执行:
CompletableFuture
利用ForkJoinPool.commonPool()
线程池来执行异步任务,通过AsynchronousCompletionTask
接口实现任务的异步执行。 - 链式调用: 通过在
CompletableFuture
对象上注册回调函数实现链式调用。当一个CompletableFuture
完成时,会触发注册的回调函数,回调函数可以对结果进行处理并返回新的CompletableFuture
。 - 并行执行:
allOf
方法通过创建一个新的CompletableFuture
,并等待所有传入的CompletableFuture
都完成,anyOf
方法则是只要有一个CompletableFuture
完成就返回。 - 异常处理:
CompletableFuture
内部通过tryCompleteThrowable
方法来设置异常,当设置异常后,会触发注册的异常处理回调函数,如exceptionally
和handle
中注册的回调。