面试题:线程池的底层工作原理

线程池的几个重要的参数:

1、corePoolSize:线程池的核心线程数(也是默认线程数)

2、maximumPoolSize:最大线程数

3、keepAliveTime:允许的线程最大空闲时间(单位/秒)

线程池内部是通过队列+线程实现的,当我们利用线程池执行任务时:

  • 如果此时线程池中的线程数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务,

  • 如里此时线程池中的线程数量等于corePoolSize,但是缓冲队列workQueue未满,那么任务被放入缓冲队列。

  • 如果此时线程池中的线程数量大于等于corePoolSize,缓中队列workQueue满,并且线程池中的数量小于maximumPooISize,建新的线程来外理被添加的任务。

  • 如果此时线程池中的线程数量大于corePoosize,缓冲队列workQueue满,并目线程池中的数量等于maximumPoosize,那么通过 handler所指定的策略来处理此任务。

  • 当线程池中的线程数量大于 corePoolsize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程可以动态的调整池中的线程数。

线程池的拒绝策略:指的是RejectedExecutionHandler接口的实现类。

在线程池接口的源代码中,可以发现ThreadPoolExecutor接口内置了4种拒绝策略。

java 复制代码
package java.util.concurrent;


public class ThreadPoolExecutor extends AbstractExecutorService {

    /**
     * A handler for rejected tasks that runs the rejected task
     * directly in the calling thread of the {@code execute} method,
     * unless the executor has been shut down, in which case the task
     * is discarded.
     */
    public static class CallerRunsPolicy implements RejectedExecutionHandler {
        /**
         * Creates a {@code CallerRunsPolicy}.
         */
        public CallerRunsPolicy() { }

        /**
         * Executes task r in the caller's thread, unless the executor
         * has been shut down, in which case the task is discarded.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                r.run();
            }
        }
    }

    /**
     * A handler for rejected tasks that throws a
     * {@code RejectedExecutionException}.
     */
    public static class AbortPolicy implements RejectedExecutionHandler {
        /**
         * Creates an {@code AbortPolicy}.
         */
        public AbortPolicy() { }

        /**
         * Always throws RejectedExecutionException.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         * @throws RejectedExecutionException always
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() +
                                                 " rejected from " +
                                                 e.toString());
        }
    }

    /**
     * A handler for rejected tasks that silently discards the
     * rejected task.
     */
    public static class DiscardPolicy implements RejectedExecutionHandler {
        /**
         * Creates a {@code DiscardPolicy}.
         */
        public DiscardPolicy() { }

        /**
         * Does nothing, which has the effect of discarding task r.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        }
    }

    /**
     * A handler for rejected tasks that discards the oldest unhandled
     * request and then retries {@code execute}, unless the executor
     * is shut down, in which case the task is discarded.
     */
    public static class DiscardOldestPolicy implements RejectedExecutionHandler {
        /**
         * Creates a {@code DiscardOldestPolicy} for the given executor.
         */
        public DiscardOldestPolicy() { }

        /**
         * Obtains and ignores the next task that the executor
         * would otherwise execute, if one is immediately available,
         * and then retries execution of task r, unless the executor
         * is shut down, in which case task r is instead discarded.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                e.getQueue().poll();
                e.execute(r);
            }
        }
    }

}

四种拒绝策略的相关说明:

1、AbortPolicy:

默认。拒绝这个任务,并且抛出RejectedExecutionException异常。

2、DiscardPolicy:

队列满了,丢掉任务,不会抛出异常!

3、DiscardOldestPolicy

队列满了,尝试去和最早的竞争,也不会抛出异常!

抛弃最老任务策略,也就是说如果队列满了,就会将最早进入队列的任务抛弃,从队列中腾出空间,再尝试加入队列。因为队列是队尾进、队头出,队头元素是最老的,所以每次都是移除队头元素后再尝试入队。

4、CallerRunsPolicy

调用者执行策略。在新任务被添加到线程池时,如果添加失败,那么提交任务的线程会自己去执行该任务,不会使用线程池中的线程去执行新任务。

相关推荐
学长毕设19 分钟前
基于springboot的社区养老监护系统的设计与实现
java·spring boot·后端
会编程的吕洞宾23 分钟前
RAG检索质量怎么评估?3个指标+LLM裁判实战
java·开发语言·人工智能·后端
卢总霸气26 分钟前
上海交大机动学院学位论文参考文献Zotero CSL 样式-2026
java
段一凡-华北理工大学31 分钟前
高炉能源系统智能化:热风炉、煤气与极致能效~系列文章07:高炉煤气:产生规律与全厂用户平衡
java·前端·能源
咖啡八杯36 分钟前
Redis 工具封装:RedisCache 对 Operations 体系的二次封装
java·数据库·redis·缓存·框架·springboot·若依
wno70442 分钟前
Springboot国际化信息(i18n)解析
java·spring boot·后端
考研保研资料分享42 分钟前
2025数学保研北交大:三校预推免、英文自介与方向选择
面试
eleven_4u1 小时前
QPS如何计算,如何部署架构
java·linux·运维·jvm·中间件
牧瀬クリスだ1 小时前
Redis Hash实战:高效存储对象与购物车
java·数据库·redis·算法·哈希算法
文丑颜不良啊1 小时前
LeetCode1141~1160题目解析
java·leetcode