- 处理机制:
- 在
CompletableFuture
的thenApply
链中,如果前面的异步任务抛出异常,thenApply
不会直接捕获这个异常。但是可以通过exceptionally
方法来优雅地处理异常。exceptionally
方法会在CompletableFuture
处于异常完成状态时被调用,它接收一个Function
作为参数,该Function
的输入是异常,返回值是在异常情况下要返回的结果,从而可以在异常发生时进行补救操作。
- 代码示例:
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureExceptionHandling {
public static void main(String[] args) {
CompletableFuture.supplyAsync(() -> {
if (Math.random() > 0.5) {
throw new RuntimeException("模拟异常");
}
return "正常结果";
})
.thenApply(result -> {
System.out.println("处理正常结果: " + result);
return result.toUpperCase();
})
.exceptionally(ex -> {
System.out.println("捕获到异常: " + ex.getMessage());
return "异常时的默认结果";
})
.thenAccept(System.out::println);
try {
// 如果没有使用exceptionally处理异常,这里会抛出异常
String result = CompletableFuture.supplyAsync(() -> {
throw new RuntimeException("模拟未处理异常");
})
.thenApply(String::toUpperCase)
.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
- 不同处理方式对程序流程的影响:
- 使用
exceptionally
处理异常:程序流程不会被中断,exceptionally
捕获异常后返回一个默认值或进行其他补救操作,后续的thenApply
、thenAccept
等方法依然可以按照顺序执行,程序可以继续进行后续逻辑。例如上述代码中,即使前面抛出异常,exceptionally
返回默认结果后,thenAccept
依然会打印这个结果。
- 不使用
exceptionally
处理异常:如果异步任务抛出异常且没有使用exceptionally
处理,那么当调用get
方法获取结果时,会抛出ExecutionException
和InterruptedException
(如果线程在等待过程中被中断),程序流程会被中断,后续代码无法正常执行,需要在调用处捕获并处理这些异常,否则程序可能会崩溃。