什么是线程池?
核心思想: 线程池是一种基于'池化'思想来管理线程的工具。它预先创建好一定数量的线程,放入一个'池子'中,当有任务需要执行时,就从池子中取出一个空闲线程来执行任务,任务执行完毕后,线程并不被销毁,而是返回池中等待执行下一个任务。
为什么需要线程池?
在深入原理之前,我们先想想如果不使用线程池,我们如何处理多任务:
// 原始方式:为每个任务创建一个新线程
for (int i = 0; i < 100; i++) {
new Thread(() -> {
// 执行任务
System.out.println("执行任务:" + Thread.currentThread().getName());
}).start();
}
这种方式存在几个严重问题:
- 资源消耗大:创建和销毁线程是非常消耗 CPU 和内存的。当任务数量非常多时,频繁地创建和销毁线程会严重影响性能。
- 管理困难:无法控制线程的数量,如果并发任务过多,会创建大量线程,导致系统负载过高,甚至崩溃。
- 稳定性差:缺乏统一的管理,线程之间的竞争和不可预知的行为会增加系统的不稳定性。
线程池的优势:
- 降低资源消耗:通过复用已创建的线程,避免了频繁创建和销毁线程的开销。
- 提高响应速度:当任务到达时,无需等待线程创建就能立即执行。
- 提高线程的可管理性:线程是稀缺资源,线程池可以统一进行分配、调优和监控。可以控制最大并发数,防止无限制创建线程。
- 提供更强大的功能:线程池提供了定时执行、定期执行、单线程、并发数控制等功能。
线程池的核心工作原理
要理解线程池的工作原理,我们需要深入到它的内部组件和执行流程。其核心模型可以用下图清晰地展示:

下面我们来详细拆解图中的每一步。
核心组件
- 核心线程池 (
corePoolSize):线程池中常驻的'核心部队'。即使它们处于空闲状态,也不会被销毁(除非设置了allowCoreThreadTimeOut为 true)。 - 任务队列 (
workQueue):一个阻塞队列,用于存放待执行的任务。当核心线程都在忙时,新来的任务会被放在这个队列里排队等候。 - 最大线程池 (
maximumPoolSize):线程池允许创建的最大线程数量。这是线程池的'扩编上限'。 - 非核心线程:当任务队列满了,并且当前线程数小于最大线程数时,线程池会创建新的线程来处理任务。这些线程是'临时工',空闲一段时间后(由
keepAliveTime决定)会被销毁。 - :当任务队列已满,并且线程数已达到最大值时,线程池会采取一种策略来处理新提交的任务。


