MST

星途 面试题库

面试题:Java CompletableFuture exceptionally在复杂异步流程中的异常处理优化

假设有一个复杂的异步任务链,其中包含多个CompletableFuture的thenApply、thenCompose等操作,并且任务之间存在依赖关系。在这个任务链中,某些任务可能会抛出特定类型的业务异常,某些可能会抛出系统异常。请设计一个全面的异常处理策略,使用exceptionally方法以及其他合适的CompletableFuture方法,确保不同类型的异常能够被正确捕获和处理,同时保证整个任务链的执行逻辑完整性,并且尽可能减少资源浪费和性能损耗。请详细说明设计思路并提供关键代码片段。
24.8万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 统一异常处理入口:利用CompletableFutureexceptionally方法来捕获任务链中的异常。这个方法会在CompletableFuture发生异常时被调用,从而提供一个统一的异常处理入口。
  2. 区分异常类型:在exceptionally方法中,通过instanceof关键字区分业务异常和系统异常,以便进行不同的处理。
  3. 恢复执行逻辑:对于业务异常,可以根据业务需求进行特定处理,如记录日志、返回默认值或进行补偿操作。对于系统异常,除了记录日志外,可能需要采取更激进的措施,如终止整个任务链或进行系统级别的恢复操作。
  4. 减少资源浪费和性能损耗:避免在异常处理过程中进行不必要的计算或I/O操作,尽量保持处理逻辑的简洁高效。在捕获异常后快速做出响应,避免长时间阻塞或资源占用。

关键代码片段

import java.util.concurrent.CompletableFuture;

// 假设这是业务异常类
class BusinessException extends RuntimeException {
    public BusinessException(String message) {
        super(message);
    }
}

// 假设这是系统异常类
class SystemException extends RuntimeException {
    public SystemException(String message) {
        super(message);
    }
}

public class CompletableFutureExceptionHandling {
    public static void main(String[] args) {
        CompletableFuture.supplyAsync(() -> {
            // 模拟可能抛出业务异常的任务
            if (Math.random() < 0.5) {
                throw new BusinessException("业务异常发生");
            }
            return "任务1完成";
        })
       .thenApply(result -> {
            // 模拟依赖前一个任务结果的任务,可能抛出系统异常
            if (Math.random() < 0.5) {
                throw new SystemException("系统异常发生");
            }
            return result + " -> 任务2完成";
        })
       .exceptionally(ex -> {
            if (ex instanceof BusinessException) {
                // 处理业务异常
                System.err.println("捕获到业务异常: " + ex.getMessage());
                return "业务异常处理结果";
            } else if (ex instanceof SystemException) {
                // 处理系统异常
                System.err.println("捕获到系统异常: " + ex.getMessage());
                // 这里可以进行系统级别的处理,如终止任务链等
                return "系统异常处理结果";
            }
            return "未知异常处理结果";
        })
       .thenAccept(System.out::println);
    }
}

在上述代码中:

  • supplyAsync方法启动一个异步任务,这个任务可能抛出BusinessException
  • thenApply方法基于前一个任务的结果进行操作,并且可能抛出SystemException
  • exceptionally方法捕获整个任务链中的异常,通过instanceof区分异常类型并进行相应处理。最终的处理结果会传递给thenAccept方法进行输出。