MST

星途 面试题库

面试题:Java CompletableFuture在高并发场景下的异常处理

在高并发场景中,多个CompletableFuture任务并行执行。请描述如何在这些任务执行过程中捕获和处理异常,确保即使部分任务出错,整体的业务逻辑仍能尽可能正常运行。并且给出相应的代码示例,要求代码中至少包含三个并行任务,其中一个任务故意设置会抛出异常。
11.0万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

在高并发场景中,CompletableFuture提供了几种处理异常的方式,确保即使部分任务出错,整体业务逻辑仍能尽可能正常运行。以下是处理异常的常见方法及代码示例:

  1. 使用exceptionally方法:该方法用于在任务执行过程中发生异常时提供一个替代结果。
  2. 使用handle方法:此方法可以同时处理正常结果和异常情况。

代码示例

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

public class CompletableFutureExceptionHandling {
    public static void main(String[] args) {
        CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> "Task 1 completed");
        CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> {
            if (Math.random() < 0.5) {
                throw new RuntimeException("Task 2 failed");
            }
            return "Task 2 completed";
        });
        CompletableFuture<String> task3 = CompletableFuture.supplyAsync(() -> "Task 3 completed");

        CompletableFuture<Void> allTasks = CompletableFuture.allOf(task1, task2, task3);

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

        task1.thenApply(result -> {
            System.out.println("Task 1 result: " + result);
            return result;
        }).exceptionally(ex -> {
            System.out.println("Task 1 exception: " + ex.getMessage());
            return "Task 1 failed";
        }).thenAccept(System.out::println);

        task2.handle((result, ex) -> {
            if (ex != null) {
                System.out.println("Task 2 exception: " + ex.getMessage());
                return "Task 2 failed";
            } else {
                System.out.println("Task 2 result: " + result);
                return result;
            }
        }).thenAccept(System.out::println);

        task3.thenApply(result -> {
            System.out.println("Task 3 result: " + result);
            return result;
        }).exceptionally(ex -> {
            System.out.println("Task 3 exception: " + ex.getMessage());
            return "Task 3 failed";
        }).thenAccept(System.out::println);


        try {
            allTasks.get(); // 获取所有任务的结果,如果有异常会抛出
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}

解释

  1. 创建任务:创建了三个CompletableFuture任务,其中task2故意设置了可能抛出异常的逻辑。
  2. 等待所有任务完成:使用CompletableFuture.allOf方法等待所有任务完成。
  3. 处理异常
    • task1task3:使用exceptionally方法处理异常,如果任务执行成功则打印结果,否则打印异常信息并返回替代结果。
    • task2:使用handle方法同时处理正常结果和异常情况,打印相应信息并返回结果或替代结果。
  4. 获取结果:通过allTasks.get()获取所有任务的结果,如果有异常会抛出,可以在try-catch块中处理。

这样可以确保在高并发场景下,即使部分任务出错,整体业务逻辑仍能尽可能正常运行。