MST

星途 面试题库

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

在使用CompletableFuture的thenRunAsync方法时,如何指定线程池来执行后续任务?如果前面的任务抛出异常,thenRunAsync方法中的任务还会执行吗?请通过代码示例说明,并阐述异常处理机制。
10.9万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 指定线程池执行thenRunAsync后续任务
    • thenRunAsync方法有一个重载形式可以接受Executor参数,通过这个参数可以指定线程池来执行后续任务。
    • 代码示例:
import java.util.concurrent.*;

public class CompletableFutureExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(3);
        CompletableFuture.supplyAsync(() -> {
            System.out.println("Initial task executed by: " + Thread.currentThread().getName());
            return "Result";
        }).thenRunAsync(() -> {
            System.out.println("Task in thenRunAsync executed by: " + Thread.currentThread().getName());
        }, executor).whenComplete((result, throwable) -> {
            executor.shutdown();
        });
    }
}
  • 在上述代码中,supplyAsync方法启动一个异步任务,thenRunAsync方法的第二个参数executor指定了线程池来执行thenRunAsync中的任务。
  1. 前面任务抛出异常时thenRunAsync任务是否执行
    • 如果前面的任务抛出异常,thenRunAsync方法中的任务不会执行。
    • 代码示例:
import java.util.concurrent.*;

public class CompletableFutureExceptionExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(3);
        CompletableFuture.supplyAsync(() -> {
            System.out.println("Initial task executed by: " + Thread.currentThread().getName());
            throw new RuntimeException("Simulated exception");
        }).thenRunAsync(() -> {
            System.out.println("Task in thenRunAsync executed by: " + Thread.currentThread().getName());
        }, executor).whenComplete((result, throwable) -> {
            if (throwable != null) {
                System.out.println("Caught exception: " + throwable.getMessage());
            }
            executor.shutdown();
        });
    }
}
  • 在上述代码中,supplyAsync方法中抛出了一个运行时异常,thenRunAsync中的任务不会执行,通过whenComplete方法捕获到了异常。
  1. 异常处理机制
    • CompletableFuture提供了多种异常处理方法,如whenCompleteexceptionally等。
    • whenComplete方法:它接收两个参数,第一个是正常完成时的结果(如果有),第二个是异常(如果有)。通过检查第二个参数是否为null来判断是否发生异常。
    • 代码示例:
import java.util.concurrent.*;

public class CompletableFutureExceptionHandling {
    public static void main(String[] args) {
        CompletableFuture.supplyAsync(() -> {
            if (Math.random() < 0.5) {
                throw new RuntimeException("Random exception");
            }
            return "Success";
        }).whenComplete((result, throwable) -> {
            if (throwable != null) {
                System.out.println("Caught exception in whenComplete: " + throwable.getMessage());
            } else {
                System.out.println("Result: " + result);
            }
        });
    }
}
  • exceptionally方法:它接收一个Function,该Function的参数为异常,返回值是在异常发生时要返回的替代结果。
  • 代码示例:
import java.util.concurrent.*;

public class CompletableFutureExceptionallyExample {
    public static void main(String[] args) {
        CompletableFuture.supplyAsync(() -> {
            if (Math.random() < 0.5) {
                throw new RuntimeException("Random exception");
            }
            return "Success";
        }).exceptionally(throwable -> {
            System.out.println("Caught exception in exceptionally: " + throwable.getMessage());
            return "Default value";
        }).thenAccept(System.out::println);
    }
}
  • 在上述代码中,exceptionally方法捕获到异常并返回了一个默认值。