MST

星途 面试题库

面试题:Java CompletableFuture thenRun方法中的线程调度机制

当使用CompletableFuture的thenRun方法时,它是如何进行线程调度的?如果在不同的线程池中执行任务,thenRun方法的行为会有什么变化?请详细说明并结合代码示例。
41.9万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. thenRun的线程调度
    • thenRun方法是CompletableFuture中的一个方法,用于在CompletableFuture完成时执行一个无参数的Runnable任务。
    • 如果CompletableFuture是由ForkJoinPool.commonPool()(默认线程池)执行完成的,那么thenRun所执行的任务也会在这个ForkJoinPool.commonPool()中执行。
    • 如果CompletableFuture是由自定义线程池执行完成的,并且这个自定义线程池的队列未满,那么thenRun所执行的任务会被提交到这个自定义线程池执行。如果自定义线程池队列已满,任务提交可能会失败(取决于线程池的拒绝策略)。
  2. 在不同线程池中执行任务时thenRun方法的行为变化
    • CompletableFuture在不同线程池中执行完成时,thenRun所执行的任务默认会提交到完成CompletableFuture的那个线程池执行,除非使用了其他方式来指定线程池。
  3. 代码示例
import java.util.concurrent.*;

public class CompletableFutureThenRunExample {
    public static void main(String[] args) {
        ExecutorService executor1 = Executors.newFixedThreadPool(2);
        ExecutorService executor2 = Executors.newFixedThreadPool(2);

        CompletableFuture.supplyAsync(() -> {
            System.out.println("Task in executor1 is running on thread: " + Thread.currentThread().getName());
            return "Result from executor1";
        }, executor1)
       .thenRun(() -> {
            System.out.println("thenRun task is running on thread: " + Thread.currentThread().getName());
        })
       .thenRunAsync(() -> {
            System.out.println("thenRunAsync task (should be in another executor) is running on thread: " + Thread.currentThread().getName());
        }, executor2)
       .whenComplete((result, throwable) -> {
            executor1.shutdown();
            executor2.shutdown();
        });


        try {
            executor1.awaitTermination(1, TimeUnit.MINUTES);
            executor2.awaitTermination(1, TimeUnit.MINUTES);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在上述代码中:

  • supplyAsync方法在executor1线程池中执行任务。
  • 第一个thenRun方法会在executor1线程池中执行,因为CompletableFuture是由executor1完成的。
  • thenRunAsync方法指定了executor2线程池,所以它会在executor2线程池中执行。

注意,在实际应用中,要记得正确关闭线程池,如代码中使用shutdownawaitTermination方法。