MST
星途 面试题库

面试题:Java中CompletableFuture自定义线程池runAsync方法的异常处理

在使用CompletableFuture的runAsync方法结合自定义线程池时,如果异步任务执行过程中抛出异常,如何优雅地捕获并处理这个异常?请通过代码示例说明,同时阐述不同处理方式的优缺点。
26.4万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

捕获异常的方式及代码示例

  1. 使用whenComplete方法
    import java.util.concurrent.*;
    import java.util.concurrent.CompletableFuture;
    
    public class CompletableFutureExceptionHandling {
        private static final ExecutorService executor = Executors.newFixedThreadPool(10);
    
        public static void main(String[] args) {
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                if (Math.random() > 0.5) {
                    throw new RuntimeException("Simulated exception");
                }
                System.out.println("Task completed successfully");
            }, executor);
    
            future.whenComplete((v, ex) -> {
                if (ex != null) {
                    System.out.println("Caught exception: " + ex.getMessage());
                }
            }).thenRun(() -> {
                executor.shutdown();
            });
        }
    }
    
  2. 使用exceptionally方法
    import java.util.concurrent.*;
    import java.util.concurrent.CompletableFuture;
    
    public class CompletableFutureExceptionHandling2 {
        private static final ExecutorService executor = Executors.newFixedThreadPool(10);
    
        public static void main(String[] args) {
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                if (Math.random() > 0.5) {
                    throw new RuntimeException("Simulated exception");
                }
                System.out.println("Task completed successfully");
            }, executor);
    
            future.exceptionally(ex -> {
                System.out.println("Caught exception: " + ex.getMessage());
                return null;
            }).thenRun(() -> {
                executor.shutdown();
            });
        }
    }
    

不同处理方式的优缺点

  1. whenComplete方法
    • 优点
      • 可以同时处理正常结果和异常情况,能在任务完成后统一进行后续处理,无论任务成功还是失败都可以执行相同的后续逻辑。
    • 缺点
      • 无法返回一个替代结果来处理异常情况。如果需要对异常情况返回特定值用于后续链式调用,whenComplete方法不太适用。
  2. exceptionally方法
    • 优点
      • 专门用于处理异常,并且可以返回一个替代结果。这在需要根据异常情况返回不同结果以继续链式调用CompletableFuture的操作时非常有用。
    • 缺点
      • 只能处理异常情况,对于正常结果没有直接的处理方式。如果同时需要对正常结果进行处理,还需要结合其他方法(如thenApply等)。