MST

星途 面试题库

面试题:Java中CompletableFuture如何处理异步任务的异常

请阐述在Java的CompletableFuture中,有哪些方法可以用来处理异步任务执行过程中抛出的异常,并举例说明它们的使用场景和区别。
20.0万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

在Java的CompletableFuture中,处理异步任务执行过程中抛出异常的方法主要有以下几种:

  1. exceptionally方法
    • 使用场景:当异步任务出现异常时,希望返回一个默认值或者执行一些补偿操作。
    • 示例
CompletableFuture.supplyAsync(() -> {
    if (Math.random() < 0.5) {
        throw new RuntimeException("模拟异常");
    }
    return "任务正常结果";
})
.exceptionally(ex -> {
    System.out.println("捕获到异常: " + ex.getMessage());
    return "默认值";
})
.thenAccept(System.out::println);
- **区别**:该方法只处理异常情况,当任务正常完成时不会执行`exceptionally`中的代码块。

2. handle方法 - 使用场景:无论异步任务正常完成还是出现异常,都需要对结果进行统一处理。 - 示例

CompletableFuture.supplyAsync(() -> {
    if (Math.random() < 0.5) {
        throw new RuntimeException("模拟异常");
    }
    return "任务正常结果";
})
.handle((result, ex) -> {
    if (ex != null) {
        System.out.println("捕获到异常: " + ex.getMessage());
        return "默认值";
    }
    return result;
})
.thenAccept(System.out::println);
- **区别**:与`exceptionally`不同,`handle`方法无论任务是否异常都会执行,通过判断`ex`是否为`null`来确定任务是否异常。

3. 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);
    }
})
.thenApply(r -> "处理后的结果")
.thenAccept(System.out::println);
- **区别**:`whenComplete`方法只是执行一些最终操作,不改变任务的返回结果,后续的`thenApply`等方法仍会按照原任务结果或异常情况继续执行。而`exceptionally`和`handle`会返回新的结果来替代原任务结果(如果有异常)。