Java 线程池 ThreadPoolExecutor 全面入门(原理 + 核心参数 + 图解)(一)

在 Java 并发编程中,线程池(ThreadPoolExecutor) 是最重要、最常用的组件之一。
如果说 wait/notify 是“线程之间如何协作”,那么线程池就是“如何管理大量线程的创建、复用与调度”

只要你掌握了线程池的六大核心参数 + 队列类型 + 拒绝策略,你就已经掌握了 Java 并发编程的半壁江山。

一、为什么需要线程池?(必须先讲清楚)

一、为什么需要线程池?(必须先讲清楚)

new Thread(() -> doWork()).start();
 

但这样会带来很多问题:

  • ❌ 创建线程成本高(线程创建需要切栈、注册、调度等)
  • ❌ 大量线程会抢占 CPU,造成性能下降
  • ❌ JVM 无法控制线程数量,容易 OOM
  • ❌ 无法统一管理任务(比如监控、统一关闭等)
  • ❌ 不适合高并发(几千、几万任务就炸)

线程池的核心思想是:

把线程复用起来,不用每次都 new Thread,而是把任务交给线程池来调度执行。

二、线程池的核心构造器(ThreadPoolExecutor)

Java 线程池的本体就是:

public ThreadPoolExecutor( int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) 

这六个参数是理解线程池的关键,我给你讲到最透。

三、线程池六大核心参数(绝对核心)

我们逐个讲:

1)corePoolSize(核心线程数)

线程池长期存活的线程数量。

只要提交任务,核心线程池中的线程会一直存在,不会销毁(除了一些 allowCoreThreadTimeout 的特殊情况)。

2)maximumPoolSize(最大线程数)

线程池能创建的最大线程数量(核心线程 + 临时线程)。
  • 当任务很多、队列也排满时,会创建临时线程。
  • 当任务少时,这些临时线程会被回收。

3)workQueue(任务队列)

核心线程用完后,进入队列等待。

常见队列:

队列类型解释特点
LinkedBlockingQueue(默认)无界队列最常用,但可能 OOM
ArrayBlockingQueue有界队列强烈推荐用于生产
SynchronousQueue不存任务、直接交给线程用于高并发,例如 CachedThreadPool
PriorityBlockingQueue优先级队列任务可排序

队列类型直接决定线程池行为。

4)keepAliveTime(空闲线程存活时间)

临时线程空闲多久后被回收?

只对 非核心线程 生效。

5)threadFactory(线程工厂)

用于给线程自定义:

  • 名字(方便排查问题)
  • 是否为守护线程
  • 优先级

例如:

Executors.defaultThreadFactory()

6)RejectedExecutionHandler(拒绝策略)

当:

  • 线程数达到最大(maximumPoolSize)
  • 队列也满了

这时任务无法执行,就会触发 拒绝策略

JDK 提供 4 种:

策略行为
AbortPolicy(默认)直接抛异常
DiscardPolicy直接丢弃任务
DiscardOldestPolicy丢弃队列头部任务
CallerRunsPolicy由调用者线程执行任务

线上一般用 CallerRunsPolicy,让调用线程回退压力。

四、线程池工作流程(图解到你完全懂)

一个任务 submit 到线程池后,会经历以下步骤:

 ┌──────────────┐ │ 提交任务 │ └──────┬───────┘ ▼ 是否小于 corePoolSize? ├─────────── 是 ─────────→ 创建核心线程执行 │ └── 否 ▼ 队列是否能放下? ├─────────── 是 ─────────→ 进入队列等待 │ └── 否 ▼ 是否小于 maximumPoolSize? ├─────────── 是 ─────────→ 创建临时线程执行 │ └── 否 ▼ 拒绝策略 

这张流程图会非常清晰。

五、线程池的四大经典实现(你需要全部掌握)

JDK 自带 Executors 快速创建线程池的方法,但 不推荐 在实际生产使用(因为容易 OOM)。

1)FixedThreadPool(固定线程池)

Executors.newFixedThreadPool(4);

特点:

  • 核心线程 = 最大线程
  • 无界队列 → 可能 OOM
  • 适合 CPU 密集型任务

2)CachedThreadPool(缓存线程池)

Executors.newCachedThreadPool();

特点:

  • 核心线程 0
  • 最大线程 Integer.MAX_VALUE
  • SynchronousQueue(不排队)→ 能创建无限线程 → 极高并发 → 也可能炸

3)SingleThreadExecutor(单线程池)

保证任务按顺序执行。

4)ScheduledThreadPool(定时任务线程池)

功能类似 Timer,但更强大。

六、线程池最佳实践(项目级建议)

✔ 使用 有界队列(ArrayBlockingQueue),避免 OOM
✔ 手动 new ThreadPoolExecutor,不用 Executors
✔ 根据任务类型决定线程数:

  • CPU 密集:线程数 = CPU核数 + 1
  • IO 密集:线程数 = CPU核数 * 2 或更多

✔ 记得设置线程名(threadFactory)方便排查

✔ 适当使用拒绝策略做流控 → CallerRunsPolicy

七、总结(背下来即可)

线程池的核心思想:复用线程,减少创建开销。

核心参数作用:

  • corePoolSize:最小常驻线程数
  • maximumPoolSize:最大线程数
  • workQueue:任务排队的地方
  • keepAliveTime:临时线程多久回收
  • threadFactory:线程名字
  • handler:拒绝策略

线程池执行流程:
核心线程 → 队列 → 临时线程 → 拒绝策略

下一篇:

深入理解 Java 线程池(二):ThreadPoolExecutor 执行流程 + 运行状态 + ctl 原理全解析

Read more

在命令行中编译并运行 C++ 程序

--阅读《 C++ primer》读书笔记 很多初学者写完第一个 C++ 程序后,不知道如何在命令行中编译并运行。博主学了c++一年多了,一直都在IDE中开发,今天偶然学习到用命令行的方式,逐步编译运行代码,这也是为了马上要学习的Linux打点基础吧! 本文将以 Windows 系统 为例,介绍从创建文件到编译运行的完整流程,并简要说明 cl 和 g++ 两种编译器的用法。 1. 创建并编辑源文件 首先,打开命令行窗口(cmd 或 PowerShell),切换到目标文件夹,例如: cd C:\hello 接着,使用记事本创建并编辑一个源文件: notepad hello.cpp 执行后会弹出记事本,输入你的 C++ 代码并保存。 2. 使用 MSVC 编译器(cl)

By Ne0inhk
C++技术栈全景解析与最佳实践指南

C++技术栈全景解析与最佳实践指南

一、C++技术栈全景图 1. 语言核心层 text 就像学习驾驶汽车: - 基本语法(方向盘、油门、刹车) - 面向对象编程(车辆不同部件的分工协作) - 模板与泛型编程(通用零件适配不同车型) - 内存管理(油箱容量控制和加油策略) 2. 标准库(STL) text 就像家庭工具箱: - 容器:vector(可伸缩收纳箱)、map(带标签的文件柜) - 算法:排序、查找、操作工具 - 迭代器:工具箱的"抓手",统一访问方式 - 智能指针:带自动清理功能的工具(用后自动归位) 3. 系统与网络层

By Ne0inhk
libipc: 一款轻量级、跨平台的 C++ 进程间通信(IPC)库

libipc: 一款轻量级、跨平台的 C++ 进程间通信(IPC)库

目录 1.简介 2.安装 2.1.vcpkg 一键安装 2.2.源码编译安装 3.使用示例 4.项目的目录结构及介绍 5.适合的项目场景 1.简介 https://gitee.com/kanster/cpp-ipc         libipc 是一款轻量级、跨平台的 C++ 进程间通信(IPC)库,封装了管道、共享内存、消息队列等底层 IPC 机制,提供简洁的现代 C++ API,适配 Windows 和 Linux 系统。         设计理念: * 极简 API:所有功能封装在ipc命名空间下,无嵌套、

By Ne0inhk

Cursor 使用记录:C/C++ 开发者

🧭 一、安装与环境建议 1. 插件与兼容性 Cursor 基于 VS Code 1.85+,部分旧插件可能不兼容。 推荐安装以下插件: 插件名称作用C/C++ Extension Pack提供语法补全与调试支持Remote - SSH远程开发CodeLLDBC/C++ 调试Better C++ Syntax增强语法高亮GitLens代码版本追踪 如果提示 “not compatible”,可以手动安装: 或下载 .vsix 文件手动导入。 2. 远程开发配置 建议使用 Remote SSH 模式,在远程服务器上直接编译与调试。 在本地 .cursor/settings.json 中添加配置: { "remote.SSH.remotePlatform": { "your_server"

By Ne0inhk