MST

星途 面试题库

面试题:Java的CompletableFuture在处理多个异步任务时如何处理异常

假设有多个CompletableFuture异步任务并行执行,其中部分任务可能会抛出异常。请描述如何使用CompletableFuture的相关方法来捕获和处理这些异常,同时保证其他未抛出异常的任务能正常执行并获取结果。请提供示例代码。
45.0万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 捕获异常并继续执行其他任务的方法

    • 使用CompletableFuture.allOf方法来等待所有异步任务完成。allOf接受多个CompletableFuture作为参数,并返回一个新的CompletableFuture,当所有传入的CompletableFuture都完成时,这个新的CompletableFuture才完成。
    • 对于每个CompletableFuture,可以使用exceptionally方法来处理可能抛出的异常。exceptionally方法接受一个Function,当CompletableFuture抛出异常时,这个Function会被调用,返回一个替代结果。
  2. 示例代码

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

public class CompletableFutureExceptionHandling {
    public static void main(String[] args) {
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            // 模拟一个可能抛出异常的任务
            if (Math.random() > 0.5) {
                throw new RuntimeException("Task 1 failed");
            }
            return 10;
        });

        CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
            // 模拟一个正常执行的任务
            return 20;
        });

        CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2);

        allFutures.join(); // 等待所有任务完成

        try {
            Integer result1 = future1.exceptionally(ex -> {
                System.out.println("Caught exception in future1: " + ex.getMessage());
                return -1; // 异常时的替代结果
            }).get();
            Integer result2 = future2.get();

            System.out.println("Result of future1: " + result1);
            System.out.println("Result of future2: " + result2);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}

在上述代码中:

  • future1模拟了一个可能抛出异常的异步任务。
  • future2模拟了一个正常执行的异步任务。
  • CompletableFuture.allOf等待future1future2都完成。
  • future1.exceptionally捕获future1可能抛出的异常,并返回一个替代结果。
  • 最后通过get方法获取任务结果,future1即使抛出异常也不会影响future2的执行和结果获取。