【故事版】线程池七大参数:开餐厅招服务员的故事,面试官最爱问的就是它

2026/10/25 Java

故事场景:老郑餐厅开业了

你在美食街开了家餐厅,生意火爆,服务员怎么招、客人怎么安排,直接决定餐厅会不会被挤爆。这套人事制度,就是 ThreadPoolExecutor 的七大参数——面试官最爱拿它挖坑,咱们今天用开餐厅的故事一次讲透。

先认识一下餐厅的”编制表”

餐厅角色 线程池参数 说明
常驻服务员 corePoolSize 每天固定到岗的正式员工数
临时工上限 maximumPoolSize 忙不过来时最多能再招多少人(含常驻)
等位区 workQueue 门口排队等位的椅子数
临时工摸鱼开除线 keepAliveTime 临时工闲置多久没活干就结账走人
时间单位 unit 上面那个时间是秒还是分钟
招聘方式 threadFactory 统一招人、培训、编号(给线程起名,排查问题时救命)
店长应急预案 handler 人也满了、队也满了,新客人怎么办(拒绝策略)

上客顺序:面试最爱挖的坑就在这里

很多朋友以为”忙不过来先招临时工”,错! 餐厅的真实顺序是这样的:

  1. 先喊常驻服务员。 客人(任务)来了,常驻服务员没站满,先招正式员工来服务(核心线程数未满 → 新建核心线程)。
  2. 常驻全忙着 → 客人去等位区坐着。 注意这一步:不是招临时工,而是先进阻塞队列排队。等位区有空椅子,任务就乖乖等着,常驻服务员忙完一个接一个。
  3. 等位区也坐满了 → 这才开始招临时工。 队列满了,才新建非核心线程,直到达到 maximumPoolSize。
  4. 临时工招满、等位区也满 → 店长启动应急预案(拒绝策略)。

把这个顺序记牢,面试至少一半的线程池问题就通了:核心线程 → 阻塞队列 → 最大线程 → 拒绝策略。

四种店长应急预案(拒绝策略)

  • AbortPolicy(默认): 直接关门谢客,贴告示”今日客满”——抛出 RejectedExecutionException。态度强硬,但至少你知道出事了。
  • CallerRunsPolicy: 店长自己端盘子——谁提交的任务谁自己执行(调用者线程亲自跑)。不丢任务,还能天然限流,是线上最常用的兜底。
  • DiscardPolicy: 悄悄把新客人请走,不吭声——任务直接丢弃,不抛异常。适合能丢的任务,比如无关紧要的日志。
  • DiscardOldestPolicy: 把等位最久的客人请走,给新客人腾地方——丢弃队列头部的最老任务。适合”只要最新数据”的场景,比如实时行情。

为什么阿里规约不让用 Executors 快捷创建?

Executors 就像中介给你打包好的”招聘套餐”,看着省事,坑都埋在编制表里:

  • newFixedThreadPool / newSingleThreadExecutor:等位区是无界队列(椅子无限多)。客人永远不会触发招临时工,只会无限排队,最后任务堆积把内存撑爆(OOM)。
  • newCachedThreadPool:临时工没有上限。高峰一来招出几万个线程,系统直接被拖垮。

所以《阿里巴巴 Java 开发手册》明确要求:手动 new ThreadPoolExecutor,把七个参数写明白。

参数到底怎么设?

没有银弹,但有经验公式做起点,再靠压测微调:

  • CPU 密集型(算得多的活,如加解密、复杂计算):线程数 ≈ CPU 核数 + 1,多了纯属上下文切换浪费。
  • IO 密集型(等得多的活,如查数据库、调接口):线程数 ≈ CPU 核数 × 2 起步,等待时间越长可以设得越大。
ThreadPoolExecutor pool = new ThreadPoolExecutor(
5, // 常驻服务员 5 人
15, // 最多 15 人
60L, TimeUnit.SECONDS, // 临时工闲置 60 秒离场
new ArrayBlockingQueue<>(20), // 等位区 20 把椅子(有界!)
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy()); // 店长亲自端盘子

想再往深走一步,我早年写过一篇《Java并发-Executor框架》,把执行器框架的来龙去脉捋过一遍,可以配合这篇一起看;另外 Java 21 的虚拟线程出来之后,”餐厅要不要干脆改成自助餐”也是个新话题,我在《Java 21 虚拟线程 vs. 传统线程》里聊过,结论是:虚拟线程适合 IO 密集场景,但线程池的基本功该练还得练。

简单粗暴地说: 线程池就是一家餐厅的用人制度——常驻保底、排队缓冲、临时工封顶、满员有预案。参数怎么设,本质是回答一个问题:你的活,是算得多,还是等得多?

怎么样,老铁!下次面试官问”线程池参数怎么设置”,别背八股,把这家餐厅端出来,边讲故事边把执行顺序和拒绝策略带出来,这题就稳了。

顺手安利:调接口、验时间戳、试 Cron 表达式这类小活儿,我做了个在线工具箱 itupload.cn,打开就用。

Show Disqus Comments

Search

    Post Directory