MST

星途 面试题库

面试题:Java中CompletableFuture的supplyAsync与runAsync在方法签名上有何区别

请详细阐述Java中CompletableFuture类的supplyAsync方法与runAsync方法在方法签名上的具体不同点,并说明这种不同会对使用场景产生怎样的影响。
18.9万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

方法签名不同点

  1. supplyAsync方法签名
    • 有两个重载形式:
      • public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
      • public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor)
    • 第一个参数是Supplier<U>类型,Supplier是一个函数式接口,它有一个get方法,该方法无参数,返回一个U类型的结果。这个方法会返回一个CompletableFuture<U>,泛型U就是Supplier返回的类型。
  2. runAsync方法签名
    • 同样有两个重载形式:
      • public static CompletableFuture<Void> runAsync(Runnable runnable)
      • public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)
    • 第一个参数是Runnable类型,Runnable也是一个函数式接口,它只有一个run方法,该方法无参数且无返回值(void)。这个方法返回的是CompletableFuture<Void>,表示该异步操作不返回有意义的值。

对使用场景的影响

  1. supplyAsync适用场景
    • 当异步任务需要返回一个计算结果时使用。例如,从数据库查询数据、进行复杂的数学计算等场景。假设我们要异步计算两个数的和并返回结果:
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
    int a = 10;
    int b = 20;
    return a + b;
});
future.thenAccept(System.out::println);
  1. runAsync适用场景
    • 当异步任务只是执行一些操作,不需要返回结果时使用。比如,异步记录日志、异步清理缓存等。例如,我们要异步执行一个日志记录操作:
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
    System.out.println("Logging some information asynchronously...");
});
future.thenRun(() -> System.out.println("Log operation completed"));
  • 因为runAsync不返回有意义的值,所以后续的链式调用更侧重于在任务完成后执行其他操作,而不是基于返回值进行处理。