MST
星途 面试题库

面试题:Java线程池处理任务时队列满了且线程数达到最大值的应对机制

当Java线程池中的任务队列已满,并且线程数量已经达到了maximumPoolSize,此时再有新任务提交,线程池会如何处理?请说明具体的处理逻辑以及涉及到的相关类和方法。
28.6万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 处理逻辑
    • 当Java线程池中的任务队列已满,并且线程数量已经达到了maximumPoolSize,此时再有新任务提交,线程池会根据所使用的饱和策略来处理。
    • 饱和策略定义了线程池在无法接受新任务时的行为,默认情况下,线程池使用的是AbortPolicy
  2. 相关类和方法
    • ThreadPoolExecutor
      • 线程池的核心类,它实现了ExecutorService接口。ThreadPoolExecutor类有多个构造函数,例如:
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler)
 - 其中`corePoolSize`是核心线程数,`maximumPoolSize`是最大线程数,`workQueue`是任务队列,`handler`就是用来指定饱和策略的。
  • RejectedExecutionHandler接口
    • 该接口定义了线程池饱和时的处理策略,它只有一个方法:
void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
  • 常见的饱和策略实现类
    • AbortPolicy
      • 这是默认的饱和策略。当任务无法处理时,它会抛出RejectedExecutionException异常。
      • 代码示例:
ThreadPoolExecutor executor = new ThreadPoolExecutor(
        2,  // corePoolSize
        4,  // maximumPoolSize
        10, TimeUnit.SECONDS,
        new ArrayBlockingQueue<>(2),  // 任务队列大小为2
        new ThreadPoolExecutor.AbortPolicy());  // 使用默认的AbortPolicy
executor.submit(() -> {
    // 任务逻辑
});
 - **`CallerRunsPolicy`**:
   - 当任务被拒绝时,该策略会让调用者线程来执行被拒绝的任务。这样可以降低新任务的提交速度。
   - 代码示例:
ThreadPoolExecutor executor = new ThreadPoolExecutor(
        2,  // corePoolSize
        4,  // maximumPoolSize
        10, TimeUnit.SECONDS,
        new ArrayBlockingQueue<>(2),  // 任务队列大小为2
        new ThreadPoolExecutor.CallerRunsPolicy());  // 使用CallerRunsPolicy
executor.submit(() -> {
    // 任务逻辑
});
 - **`DiscardPolicy`**:
   - 该策略会直接丢弃被拒绝的任务,不会有任何提示。
   - 代码示例:
ThreadPoolExecutor executor = new ThreadPoolExecutor(
        2,  // corePoolSize
        4,  // maximumPoolSize
        10, TimeUnit.SECONDS,
        new ArrayBlockingQueue<>(2),  // 任务队列大小为2
        new ThreadPoolExecutor.DiscardPolicy());  // 使用DiscardPolicy
executor.submit(() -> {
    // 任务逻辑
});
 - **`DiscardOldestPolicy`**:
   - 该策略会丢弃任务队列中最老的一个任务(即最早进入队列的任务),然后尝试提交新任务。
   - 代码示例:
ThreadPoolExecutor executor = new ThreadPoolExecutor(
        2,  // corePoolSize
        4,  // maximumPoolSize
        10, TimeUnit.SECONDS,
        new ArrayBlockingQueue<>(2),  // 任务队列大小为2
        new ThreadPoolExecutor.DiscardOldestPolicy());  // 使用DiscardOldestPolicy
executor.submit(() -> {
    // 任务逻辑
});