MST
星途 面试题库

面试题:Java CompletableFuture thenRun 方法的线程调度与异常处理

假设你使用 CompletableFuture 的 thenRun 方法链式调用多个异步任务,在这个过程中,如何确保 thenRun 方法中的任务在特定的线程池中执行?并且,如果前序异步任务抛出异常,thenRun 方法中的任务还会执行吗?如果不会,应该如何处理这种情况以确保有相应的补救措施?请给出代码示例说明。
40.3万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 确保thenRun方法中的任务在特定线程池中执行
    • CompletableFuturethenRun方法可以通过调用thenRunAsync方法并传入自定义的Executor来实现在特定线程池中执行任务。Executor可以是Executors工具类创建的线程池,也可以是自定义的线程池。
  2. 前序异步任务抛出异常时thenRun方法中的任务执行情况
    • 如果前序异步任务抛出异常,thenRun方法中的任务不会执行。
  3. 处理异常并确保有补救措施
    • 可以使用exceptionally方法来捕获前序任务的异常,并在捕获到异常时执行补救措施。 以下是代码示例:
import java.util.concurrent.*;

public class CompletableFutureExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(3);
        CompletableFuture.supplyAsync(() -> {
            // 模拟一个可能抛出异常的异步任务
            if (Math.random() > 0.5) {
                throw new RuntimeException("任务执行出错");
            }
            return "任务正常完成";
        })
       .thenRunAsync(() -> System.out.println("这是thenRunAsync中的任务,在特定线程池中执行"), executor)
       .exceptionally(ex -> {
            System.out.println("捕获到异常: " + ex.getMessage());
            // 执行补救措施
            return "补救措施执行结果";
        })
       .thenAccept(System.out::println);

        executor.shutdown();
    }
}

解释:

  1. supplyAsync方法开始一个异步任务。
  2. thenRunAsync方法传入自定义的Executor(这里是executor线程池),确保其中的任务在特定线程池中执行。
  3. exceptionally方法捕获前序任务的异常,并执行补救措施,返回补救措施的结果。
  4. thenAccept方法接收最终结果(正常结果或补救措施的结果)并打印。最后关闭线程池。