Java面试初中级:线程池的主要参数有哪些?
hello啊,各位观众姥爷们!!!本baby今天又来报道了!哈哈哈哈哈嗝🐶
程序员各种工具大全
线程池的核心参数直接影响其行为、性能和资源控制,以下是以 Java ThreadPoolExecutor
为例的 7 个核心参数及其作用:
1. 核心线程数 (corePoolSize
)
- 定义:常驻线程数量(即使空闲也不会被回收)。
- 行为:
- 线程池初始化时 不会立即创建线程(懒加载)。
- 当任务数 ≤
corePoolSize
时,每次提交任务都创建新线程。
- 建议:
- 根据 CPU 核心数 或 业务特性 设置(如长期需要 5 个任务并行,则
core=5
)。
- 根据 CPU 核心数 或 业务特性 设置(如长期需要 5 个任务并行,则
2. 最大线程数 (maximumPoolSize
)
- 定义:线程池允许的最大线程数(包括核心线程+非核心线程)。
- 行为:
- 当任务数 >
corePoolSize
且 队列已满 时,创建新线程直到达到此上限。
- 当任务数 >
- 示例:
core=5
,max=10
:队列满后最多可再扩容 5 个临时线程。
- ⚠️ 坑点:设置过大可能导致资源耗尽(如内存溢出)。
3. 线程空闲存活时间 (keepAliveTime
+ TimeUnit
)
- 定义:非核心线程(
线程数 > corePoolSize
的线程)空闲超过此时间后被回收。 - 行为:
- 默认只作用于非核心线程。
- 通过
allowCoreThreadTimeOut(true)
可使核心线程超时回收。
- 示例:
keepAliveTime=30s
:非核心线程空闲 30 秒后自动销毁。
4. 任务队列 (workQueue
)
-
作用:缓存待执行任务的阻塞队列。
-
常用队列类型:
队列类型 特性 适用场景 ArrayBlockingQueue
有界队列(固定容量) 需严格控制资源的系统 LinkedBlockingQueue
可选有界/无界(默认 Integer.MAX_VALUE
)读多写少(如 Web 请求缓冲) SynchronousQueue
零容量队列(直接传递任务) 高吞吐、短任务场景 PriorityBlockingQueue
按优先级排序的队列 需按优先级执行任务 -
⚠️ 关键影响:
- 无界队列(如
LinkedBlockingQueue
)→ 不会触发扩容到maxPoolSize
,但有 OOM 风险。 - 有界队列 → 队列满后才扩容线程,但可能触发拒绝策略。
- 无界队列(如
5. 线程工厂 (ThreadFactory
)
- 作用:自定义线程创建过程(名称、优先级、守护状态等)。
- 最佳实践:
// 自定义线程命名(便于排查问题) Executors.defaultThreadFactory().newThread(r -> new Thread(r, "order-thread-" + threadCounter.getAndIncrement()) );
- 意义:将默认命名
pool-1-thread-2
改为业务语义(如payment-thread-3
)。
6. 拒绝策略 (RejectedExecutionHandler
)
-
触发条件:任务数 >
maxPoolSize
且 队列已满。 -
内置策略:
策略 行为 AbortPolicy
(默认)抛 RejectedExecutionException
CallerRunsPolicy
由提交任务的线程自己执行任务(降级) DiscardPolicy
静默丢弃新任务(无通知) DiscardOldestPolicy
丢弃队列中最老的任务,重试提交当前任务 -
生产建议:
- 优先选择
CallerRunsPolicy
(避免任务丢失,但可能拖慢主线程)。 - 日志监控或告警应集成到自定义拒绝策略中。
- 优先选择
参数间协作总结
- 任务提交时:
- 先尝试用核心线程 (
corePoolSize
) → 失败则入队 (workQueue
) → 队列满则扩容到最大线程 (maximumPoolSize
) → 仍满则拒绝 (RejectedExecutionHandler
)。
- 先尝试用核心线程 (
- 线程回收:
- 非核心线程空闲超时 (
keepAliveTime
) 后被回收。
- 非核心线程空闲超时 (
- 线程命名:
ThreadFactory
统一管理线程标识。
生产环境配置示例
ThreadPoolExecutor executor = new ThreadPoolExecutor(4, // corePoolSize (4 核 CPU 常驻 4 线程)8, // maximumPoolSize (突发流量最大 8 线程)30, TimeUnit.SECONDS, // 非核心线程空闲 30 秒回收new ArrayBlockingQueue<>(100), // 有界队列(容量 100,避免 OOM)new CustomThreadFactory("order-service"), // 自定义线程命名new CallerRunsPolicy() // 队列满时由主线程执行(降级)
);
关键参数经验公式
- CPU 密集型任务(计算为主):
corePoolSize = CPU 核数 + 1
- I/O 密集型任务(网络/DB 请求):
corePoolSize = CPU 核数 * [1 + (I/O 耗时 / CPU 耗时)]
(通常取2 * CPU 核数
) - 队列容量:根据业务容忍延迟设置(如最大积压 1000 个任务)。
- 最大线程数:不超过系统最大线程数限制(如 Linux 默认 1024)。