MST

星途 面试题库

面试题:Java 中 CompletableFuture 复杂异步任务链的异常处理与顺序优化

在一个复杂的业务场景中,有一系列通过 CompletableFuture 构建的异步任务链,任务链中可能会出现多种类型的异常。要求实现:1. 对不同类型的异常进行针对性处理,避免异常中断整个任务链影响后续可执行任务。2. 对任务链的执行顺序进行优化,在满足业务逻辑的前提下尽量提高执行效率。请详细阐述你的设计思路,并提供核心代码示例及注释。
34.9万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 异常处理:利用 CompletableFutureexceptionally 方法,针对不同类型的异常创建多个 CompletableFuture 分支来处理异常,确保异常不会中断整个任务链。通过自定义异常类型或者使用 instanceof 判断异常类型,为每种异常类型提供专门的处理逻辑。
  2. 执行顺序优化:分析业务逻辑,确定哪些任务可以并行执行。使用 CompletableFuture.allOfCompletableFuture.anyOf 方法将可以并行的任务包装起来,以提高执行效率。同时,对于有依赖关系的任务,按照依赖顺序正确构建任务链。

核心代码示例及注释

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

// 自定义异常类型
class CustomException extends Exception {
    public CustomException(String message) {
        super(message);
    }
}

public class CompletableFutureTaskChain {

    public static void main(String[] args) {
        CompletableFuture.supplyAsync(() -> {
            // 模拟异步任务,可能抛出异常
            if (Math.random() < 0.5) {
                throw new CustomException("自定义异常发生");
            }
            return "任务1执行结果";
        })
       .thenApply(result -> {
            // 任务2依赖任务1的结果
            System.out.println("任务2接收到任务1结果: " + result);
            return "任务2执行结果";
        })
       .exceptionally(ex -> {
            // 处理自定义异常
            if (ex instanceof CustomException) {
                System.out.println("处理自定义异常: " + ex.getMessage());
                return "自定义异常处理结果";
            } else {
                // 处理其他异常
                System.out.println("处理其他异常: " + ex.getMessage());
                return "其他异常处理结果";
            }
        })
       .thenApply(result -> {
            // 任务3无论前面是否有异常,都会执行
            System.out.println("任务3接收到结果: " + result);
            return "任务3执行结果";
        })
       .thenRun(() -> {
            System.out.println("任务链执行完毕");
        })
       .join();
    }
}

代码说明

  1. 自定义异常:定义了 CustomException 用于模拟业务中的特定异常。
  2. 任务链构建
    • supplyAsync 启动第一个异步任务,该任务有一定概率抛出 CustomException
    • thenApply 方法构建依赖前一个任务结果的后续任务。
    • exceptionally 方法捕获并处理异常,针对不同类型的异常进行不同处理。
    • 后续的 thenApplythenRun 确保无论前面是否有异常,任务链都能继续执行到最后。
  3. 执行优化:在更复杂场景下,如果有可以并行执行的任务,可以将其包装在 CompletableFuture.allOf 中,例如:
CompletableFuture<String> taskA = CompletableFuture.supplyAsync(() -> "任务A结果");
CompletableFuture<String> taskB = CompletableFuture.supplyAsync(() -> "任务B结果");
CompletableFuture<Void> allTasks = CompletableFuture.allOf(taskA, taskB);
allTasks.join();
try {
    String resultA = taskA.get();
    String resultB = taskB.get();
    // 使用结果继续后续任务
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
}

这里 taskAtaskB 并行执行,allOf 等待所有任务完成,然后获取结果继续后续任务。