无界队列会让 maximumPoolSize 失效,这句 Javadoc 很少有人引

发布时间:2026/10/11 13:53:15

无界队列会让 maximumPoolSize 失效,这句 Javadoc 很少有人引 ➡️ 程序员曜灵 · 后端面试追问链 - 欢迎认识我作者程序员曜灵,绿泡泡「我要拿offer」和小红书同名。主业在一家大型央企做后端开发,Java 方向,参与过公司内部招聘面试。这里在拆高频面试题的追问链,一题三层,每层给及格线答案和大多数人挂在哪。工作日每天一篇,评论区点最高频的问题决定下一篇写什么。线程池这题我一般让人先讲七个参数。讲完 corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler,再背一遍四种拒绝策略,时间过去六分钟,内容全对。然后我问一句,你这个 workQueue 用什么。答LinkedBlockingQueue的占大多数。我接着问,那 maximumPoolSize 什么时候生效。到这里就断了。因为在你刚说的那个配置下,它永远不生效。无界队列把 maximumPoolSize 变成摆设java.util.concurrent.ThreadPoolExecutor的 Javadoc 在 Queuing 一节的 Unbounded queues 段落里写得挺直白。Thus, no more than corePoolSize threads will ever be created. (And the value of the maximumPoolSize therefore doesn’t have any effect.)前面还有一句解释为什么。无界队列永远不会满,所以队列满了才创建非核心线程这个条件永远不成立。这一句顺带解释了两件事。Executors.newFixedThreadPool为什么叫固定大小线程池,因为它内部就是无界LinkedBlockingQueue,maximumPoolSize 传进去等于没传。也解释了为什么固定池加无界队列其实是同一个坑的两种说法,队列会一直堆积任务直到 OOM,而线程数永远停在 corePoolSize。要让 maximumPoolSize 真的起作用,队列必须有界。用new ArrayBlockingQueue(capacity)建池,队列满了才会往 core 之外扩线程,扩到 maximumPoolSize 再触发拒绝策略。corePoolSize 那句永不销毁有个例外很多文章写核心线程即使没有任务也保持存活。Javadoc 的原文后面还挂着半句。corePoolSize - the number of threads to keep in the pool, even if they are idle, unlessallowCoreThreadTimeOutis setallowCoreThreadTimeOut(boolean)一旦设成 true,keepAliveTime 就开始管核心线程,空闲的核心线程也会被回收。低峰期线程数能掉到零。keepAliveTime 默认碰不到核心线程同一段 Javadoc 里,keepAliveTime 的定义前面有个限定从句。keepAliveTime - when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating.when the number of threads is greater than the core。默认情况下这个参数只对超出 core 的那部分线程生效。把keepAliveTime 是线程空闲多久后销毁当成完整答案,少了一个前提。现在说一个正在过时的规矩阿里巴巴 Java 开发手册里那条【强制】写的是不允许使用Executors创建线程池,要走ThreadPoolExecutor,理由是资源耗尽。手册说明分两条,FixedThreadPool和SingleThreadPool的请求队列允许Integer.MAX_VALUE,CachedThreadPool和ScheduledThreadPool的创建线程数允许Integer.MAX_VALUE。这条规约本身没错,它针对的是无界带来的内存风险。但它和 JDK 21 之后的官方建议撞上了。JEP 444(Virtual Threads,状态 Closed/Delivered,目标 JDK 21)给出的迁移入口就是工厂方法。Executors.newVirtualThreadPerTaskExecutor()同一份 JEP 里还有一句。Virtual threads are not expensive so there is never a need to pool them.虚拟线程不贵,所以永远不需要池化它们。规约说别用Executors,JDK 官方文档给的虚拟线程方案就叫Executors.newVirtualThreadPerTaskExecutor()。字面上打起来了。真要回答这个问题,得分场景。平台线程时代规约成立,因为线程是稀缺资源,池化的目的是复用和限流。虚拟线程时代池化这件事本身被官方否定了,需要限流的场景 JEP 444 建议用Semaphore,举的例子是某服务只能承受 20 并发。一张表把默认值和出处钉住说法实际出处队列满了才创建非核心线程仅在有界队列下成立;无界队列下 maximumPoolSize 无效ThreadPoolExecutorJavadoc,Queuing核心线程永不销毁除非设置了allowCoreThreadTimeOut同页构造参数说明keepAliveTime 是线程空闲存活时间仅当线程数大于 core 时生效同页构造参数说明禁止使用 Executors 创建线程池阿里手册【强制】,针对资源耗尽p3c 仓库p3c-gitbook/编程规约/并发处理.md虚拟线程需要池化JEP 444 明确说永远不需要openjdk.org/jeps/444面试里我会怎么分层第一层,七个参数和四个拒绝策略背齐。这是看过资料的证明,不加分。第二层,能说出无界队列下 maximumPoolSize 无效,并且知道要换ArrayBlockingQueue。到这一层我确认他写过配置,不是只背过定义。第三层,我问他线上线程池参数怎么定的。答IO 密集设 2N、CPU 密集设 N1的,我会追问这个公式哪来的。它出自《Java并发编程实战》的N_threads N_cpu × U_cpu × (1 W/C),博客版本把目标利用率U_cpu整个丢掉了,而 W/C 这两个数必须实测。说不出实测方法的,这个 2N 就是抄来的。第四层,能主动提虚拟线程和规约的冲突。这种人不常见,通常说明他在跟 JDK 21 之后的东西。出处三段 Javadoc 原文引自 OracleJava SE 21平台文档java.util.concurrent.ThreadPoolExecutor,2026-10-10 用 WebFetch 逐字核对,Java SE 25同路径也可访问。JEP 444 的编号、状态、目标版本和两句原文引自openjdk.org/jeps/444。阿里规约条目和说明文字取自 p3c 仓库的 gitbook 文本,由协作调研核对;gitbook 是早期版本,条号和【强制】标记请以你手上的《Java开发手册》正式版本再对一次。N_threads公式出自《Java并发编程实战》8.2.2 节,这一条我没有找到可访问的线上原文,按原书章节引。你如果要在面试里说这个公式,建议手边有书再讲,别只记结论。最后如果觉得这篇有用,可以点赞收藏关注 支持一下,程序员曜灵的主页还有很多按追问链拆的面试题,欢迎前去点评。哪里讲得不准,评论区指出,我改在这篇的更新里。欢迎学习交流、面试问题求助、共同进步。绿泡泡【我要拿offer】,回复 Java 拿那份按模块整理的高频面试题 PDF。想看每日面经和 offer 案例的,小红书同名号程序员曜灵。
延伸阅读

更多相关文章

2026/10/11 14:58:18

FFmpeg 3.4.2 Windows开发包:C++音视频工程静态链接实战指南

简介:本资源为FFmpeg 3.4.2版本的Windows 64位开发包(dev),专为C/C开发者集成音视频编解码能力提供底层支持,适用于多媒体应用开发、流媒体服务构建及音视频工具二次开发等场景。压缩包共160个文件,含111个…

2026/10/11 14:58:18

VC++实现POP3邮件监视系统:协议解析、UIDL判新与安全卫士风格界面

简介:这是一份基于Visual C开发的POP3邮件监视系统完整工程,界面模仿360安全卫士,面向需要学习邮件客户端开发、Winsock网络编程及MFC界面设计的VC开发者,可解决从零搭建邮件接收与图形界面整合的难题。系统实现POP3协议接收邮件、…

2026/10/11 14:58:18

直播方案PPT不是模板,而是可执行的作战地图

简介:本资源是一份面向电商运营人员、直播策划从业者及新媒体营销初学者的「主播直播方案」实战型PPT课件,聚焦直播全流程策划与落地执行,系统解决目标设定、平台选择、主播管理、内容编排、技术保障、推广引流及复盘优化等核心问题。文件为单…

2026/10/11 14:58:18

如何为InferenceX添加新模型或新GPU基准:Master YAML配置实战教程

人工智能大模型模型评测Agent 评测 【免费下载链接】InferenceX Open Source AI Accelerator Research Platform Standard / 开源推理研究平台 项目地址: https://gitcode.com/gh_mirrors/in/InferenceX 点击查看 免费下载 InferenceX 是一个开源 AI 推理加速器研究…

2026/10/11 14:58:18

开放集检测加分割实战:GroundingDINO与SAM组合落地指南

简介:结合GroundingDINO与SAM的目标检测与分割增强项目源码,面向计算机视觉算法开发者和研究人员。项目利用GroundingDINO的文本引导定位能力生成目标候选框,再由SAM输出高质量掩码,实现精确识别与细粒度分割,适用于自…

2026/10/11 14:53:18

Oracle项目实战:开放式基金交易平台数据库完整设计

简介:这是一份面向 Oracle 数据库学习者的项目实战资料,围绕开放式基金交易平台的后台数据表设计展开,适合有 SQL 基础、希望锻炼数据库建模与表结构设计能力的读者。资料完整阐述了基金公司、基金、活期账户、理财账户、基金账户、购买基金及…

2026/10/11 0:02:13

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/11 0:02:13

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/11 0:02:13

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/11 0:02:13

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/11 0:02:13

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/11 0:02:13

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑