在 Java 面试中,“线程池原理” 几乎是必考题。无论是初级开发还是资深工程师,都绕不开这个知识点 —— 毕竟线程池是 “池化思想” 的典型实践,更是项目中控制并发、优化性能的核心工具。
今天就从 “线程池为什么存在” 入手,拆解其核心原理、关键参数,再结合代码案例讲透实际应用,帮你面试时既能答清原理,又能说透实践。
一、先搞懂:为什么需要线程池?
线程虽然是轻量级的,但 “创建 + 销毁” 仍有开销 —— 每次创建线程要分配栈内存(默认 1M)、与操作系统内核交互;频繁创建销毁线程,会导致 CPU 资源浪费在 “线程管理” 上,反而影响业务执行。
线程池的作用,就是提前创建一批线程 “待命”,任务来了直接用现成线程执行,任务结束后线程不销毁,放回池里等下一个任务。这样就减少了线程创建销毁的开销,还能统一管理线程数量,避免 “线程无限创建导致 OOM” 的问题。
二、线程池核心原理:3 个核心机制 + 执行流程
线程池的核心是ThreadPoolExecutor(Java 中最基础的线程池实现),理解它要抓住 “3 个机制” 和 “1 个执行流程”。
1. 3 个核心机制:线程池的 “骨架”
-
线程管理机制:线程池内维护一批 “工作线程”(Worker),这些线程是 “活的”—— 会循环从任务队列里取任务执行,直到线程池关闭。
-
任务队列机制:当任务数超过 “核心线程数” 时,新任务会先进入阻塞队列(如LinkedBlockingQueue)等待,而不是立刻创建新线程。
-
拒绝策略机制:当任务队列满了、且线程数已达到 “最大线程数” 时,线程池会触发 “拒绝策略”(如丢弃任务、抛出异常),避免任务无限制堆积。
2. 执行流程:任务从提交到执行的全路径
当我们调用executor.execute(task)提交任务时,线程池会按以下步骤处理(结合ThreadPoolExecutor源码逻辑):
-
判断核心线程是否已满:如果当前线程数 < 核心线程数(corePoolSize),直接创建新线程执行任务;
-
核心线程满了?判断队列是否已满:如果队列没满,把任务放入队列等待;
-
队列也满了?判断最大线程是否已满:如果当前线程数 <最大线程数(maximumPoolSize),创建 “非核心线程” 执行任务;
-
最大线程也满了?触发拒绝策略:按预设的拒绝策略处理任务(如抛出RejectedExecutionException)。
用一张流程图总结:
提交任务 → 核心线程未满?→ 创建核心线程执行↓ 否任务队列未满?→ 任务入队等待↓ 否最大线程未满?→ 创建非核心线程执行↓ 否触发拒绝策略
三、关键参数:7 个参数决定线程池 “性格”
ThreadPoolExecutor的构造方法有 7 个核心参数,这些参数直接决定了线程池的 “行为模式”—— 面试时被问 “线程池参数”,其实就是问这 7 个:
public ThreadPoolExecutor(int corePoolSize, // 核心线程数int maximumPoolSize, // 最大线程数long keepAliveTime, // 非核心线程空闲存活时间TimeUnit unit, // 存活时间单位BlockingQueue<Runnable> workQueue, // 任务队列ThreadFactory threadFactory,

最低0.47元/天 解锁文章
8万+

被折叠的 条评论
为什么被折叠?



