线程池核心参数?如何设置?
这句先记住。
线程池核心参数决定了:线程池最多开多少线程?任务怎么排队?线程空闲多久回收?线程怎么创建?满了之后怎么办?
一、线程池 7 个核心参数
Java 里最常见的是ThreadPoolExecutor:
ThreadPoolExecutor( corePoolSize,//核心线程数 maximumPoolSize,//最大线程数 keepAliveTime,//空闲线程存活时间 unit,//时间单位 workQueue,//任务阻塞队列 threadFactory,//线程工厂 handler//拒绝策略 )1. corePoolSize
核心线程数。
线程池中长期保留的线程数量。
意思是:
即使线程空闲,一般也不会被回收
任务来了,优先用核心线程处理
2. maximumPoolSize
最大线程数。
线程池允许创建的最大线程数量。
如果:
核心线程都忙
队列也满了
这时候才会继续创建非核心线程,直到达到最大线程数。
3. keepAliveTime
空闲线程存活时间。
非核心线程空闲多久后会被回收。
比如最大线程数临时扩容到 20,但高峰过后空闲了,超过这个时间就会释放掉多余线程。
4. unit
keepAliveTime的时间单位。
比如秒、毫秒。
5. workQueue
任务阻塞队列。
当核心线程都在忙时,新任务先进入队列排队。
常见队列:
ArrayBlockingQueue:有界队列LinkedBlockingQueue:链表队列SynchronousQueue:不存任务,直接交给线程DelayQueue:延迟任务
6. threadFactory
线程工厂。
用来自定义创建线程,比如:
线程名称
是否守护线程
优先级
7. handler
拒绝策略。
当线程数到最大、队列也满了,再来新任务怎么办。
常见 4 种:
AbortPolicy:直接抛异常CallerRunsPolicy:让提交任务的线程自己执行DiscardPolicy:直接丢弃DiscardOldestPolicy:丢掉队列最老的任务
二、线程池执行流程
任务来了,先看核心线程满没满
没满就创建核心线程执行
满了就放进阻塞队列
队列满了,再创建非核心线程
如果线程数也到最大了,就执行拒绝策略
你只要记住这条主线:
先核心线程,再队列,再最大线程,最后拒绝策略。
三、这些参数怎么设置
1. 先分任务类型:CPU 密集型 / IO 密集型
CPU 密集型
比如:
复杂计算
加密解密
大量逻辑运算
这种任务主要吃 CPU,线程太多反而频繁切换。
一般经验是:
核心线程数 ≈ CPU 核数 或 CPU 核数 + 1
IO 密集型
比如:
查数据库
调接口
读写文件
网络请求
这种任务大部分时间在线程阻塞等待 IO。
一般线程数可以大一些,经验上:
核心线程数 ≈ CPU 核数 × 2
或者更大,结合压测定
更严谨一点可以说:
线程数 = CPU 核数 × (1 + 等待时间 / 计算时间)
2. 队列不要无脑用无界队列
这个很重要。
如果使用无界队列,比如默认很大的LinkedBlockingQueue:
任务会一直堆积
maximumPoolSize基本失效极端情况下可能 OOM
所以生产里通常更建议:
使用有界队列,防止任务无限堆积。
3. 最大线程数要结合系统承载能力
不能越大越好。
因为线程太多会带来:
频繁上下文切换
内存占用增大
系统抖动
所以最大线程数一般是在核心线程数基础上留一定弹性,用于应对流量高峰。
4. 拒绝策略要结合业务
比如:
核心任务不能丢 → 可考虑
CallerRunsPolicy非核心日志类任务可丢 → 可考虑丢弃策略
金融交易类任务一般不能静默丢弃
所以拒绝策略一定要和业务容错匹配。
四、面试里怎么讲“如何设置”?
线程池参数设置要结合任务类型和系统容量来定。
CPU 密集型任务线程数一般接近 CPU 核数,避免线程切换开销;
IO 密集型任务因为线程经常阻塞等待,所以线程数可以适当放大。队列一般建议用有界队列,避免任务无限堆积导致 OOM;最大线程数则是在核心线程数基础上预留一定扩容空间。拒绝策略要根据业务场景来选,比如核心任务不能丢时可以用 CallerRunsPolicy。最终参数通常还要结合压测结果调整,而不是写死一个万能值。
五、面试回答版
线程池核心参数主要有7 个:核心线程数 corePoolSize、最大线程数 maximumPoolSize、空闲线程存活时间 keepAliveTime、时间单位 unit、阻塞队列 workQueue、线程工厂 threadFactory 和拒绝策略 handler。
线程池执行流程一般是:任务先交给核心线程执行,核心线程满了进入队列,队列满了再创建非核心线程,超过最大线程数后触发拒绝策略。
参数设置上,一般要看任务类型:CPU 密集型任务线程数通常接近 CPU 核数,IO 密集型可以适当放大;队列建议用有界队列,避免任务无限堆积;最大线程数根据系统承载能力预留弹性;拒绝策略则要结合业务是否允许降级或丢弃。总体上线程池参数没有固定值,通常要结合业务场景和压测结果来定。
