Java 核心面试指南:线程池、JVM 内存与垃圾回收详解
在 Java 开发面试中,并发编程与 JVM 底层原理往往是区分候选人深度的关键。本文将梳理高频考点,从线程池参数配置到 JVM 内存模型,再到垃圾回收机制,帮助大家构建系统的知识体系。
一、线程池核心原理
1. 核心参数与执行流程
线程池通过七个核心参数来管理资源的生命周期和执行策略:
- corePoolSize:核心线程数。线程池维持的最小活跃线程数量。
- maximumPoolSize:最大线程数。允许创建的线程上限(核心线程 + 救急线程)。
- keepAliveTime:非核心线程的存活时间。空闲超过该时间将被回收。
- unit:存活时间的单位。
- workQueue:任务队列。当核心线程满时,新任务进入队列等待。
- threadFactory:线程工厂。用于定制线程名称、是否为守护线程等属性。
- handler:拒绝策略。当队列和线程数都达到上限时的处理方案。
执行流程简述:
- 若当前线程数小于 corePoolSize,创建新线程执行任务。
- 若核心线程已满,任务加入 workQueue。
- 若队列已满且线程数小于 maximumPoolSize,创建非核心线程执行任务。
- 若队列和线程数均满,触发 handler 拒绝策略。
2. 常见阻塞队列对比
常用的阻塞队列包括 ArrayBlockingQueue 和 LinkedBlockingQueue。
| 特性 | ArrayBlockingQueue | LinkedBlockingQueue |
|---|---|---|
| 底层结构 | 数组 | 链表 |
| 容量限制 | 强制有界 | 默认无界(可指定容量) |
| 节点创建 | 初始化时创建 | 插入时动态创建 |
| 锁机制 | 两把锁(头尾) | 一把锁(读写分离) |
LinkedBlockingQueue 采用锁分离设计,适合生产消费频率相近的场景,能减少锁竞争,提升吞吐量。
3. 核心线程数如何确定?
没有固定公式,需结合业务场景调整。一般参考 CPU 利用率、负载及 GC 频率指标进行测试。
- CPU 密集型:计算量大,上下文切换开销大。建议
CPU 核数 + 1。 - IO 密集型:涉及大量 IO 操作(如 DB、网络),线程等待 IO 时 CPU 不占用。建议
CPU 核数 * 2 + 1。 - 混合型:根据实际测试调整,平衡 CPU 利用率和响应速度。
4. 常用线程池类型
JUC 包中的 Executors 提供了四种常见实现:


