MST

星途 面试题库

面试题:Java CompletableFuture的链式调用及异常处理

使用CompletableFuture实现一个异步任务链,其中包含多个依赖的子任务,并且要处理任务执行过程中可能出现的异常,写出关键代码片段并解释思路。
13.1万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

以下是使用CompletableFuture实现异步任务链并处理异常的关键代码片段及思路解释:

关键代码片段

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

public class CompletableFutureTaskChain {
    public static void main(String[] args) {
        CompletableFuture.supplyAsync(() -> {
            // 第一个子任务
            System.out.println("执行第一个子任务");
            if (Math.random() < 0.5) {
                throw new RuntimeException("第一个子任务异常");
            }
            return "第一个子任务结果";
        })
       .thenApply(result1 -> {
            // 第二个子任务,依赖第一个子任务的结果
            System.out.println("执行第二个子任务,依赖第一个子任务结果: " + result1);
            if (Math.random() < 0.5) {
                throw new RuntimeException("第二个子任务异常");
            }
            return "第二个子任务结果";
        })
       .thenApply(result2 -> {
            // 第三个子任务,依赖第二个子任务的结果
            System.out.println("执行第三个子任务,依赖第二个子任务结果: " + result2);
            return "第三个子任务结果";
        })
       .exceptionally(ex -> {
            // 统一处理异常
            System.out.println("捕获到异常: " + ex.getMessage());
            return "默认结果";
        })
       .thenAccept(finalResult -> {
            // 最终处理结果
            System.out.println("最终结果: " + finalResult);
        });

        // 防止主线程退出
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

思路解释

  1. 第一个子任务

    • 使用CompletableFuture.supplyAsync方法创建一个异步任务,该任务会在一个新的线程中执行。
    • 在任务执行过程中,模拟了可能出现的异常情况(以50%的概率抛出异常)。
    • 如果任务成功执行,返回一个结果。
  2. 后续子任务

    • 使用thenApply方法来定义依赖前一个任务结果的后续任务。每个thenApply方法中的函数接收前一个任务的结果作为参数,并返回当前任务的结果。
    • 同样,在每个后续任务中也模拟了可能出现的异常情况。
  3. 异常处理

    • 使用exceptionally方法来统一处理任务链中任何一个任务抛出的异常。当任务链中的某个任务抛出异常时,exceptionally方法中的函数会被调用,在这个函数中可以对异常进行处理,并返回一个默认结果,使任务链能够继续执行下去。
  4. 最终结果处理

    • 使用thenAccept方法来处理任务链的最终结果。无论任务链是正常完成还是因为异常而结束,都会执行thenAccept中的操作,打印最终结果。
  5. 防止主线程退出

    • main方法中使用Thread.sleep方法来防止主线程过早退出,确保异步任务有足够的时间执行。