Java线程池一篇讲透:Executors三大方法、7大参数、4种拒绝策略

简介: Java线程池是面试高频考点。本文用银行柜台比喻拆解三大方法、7大参数与4种拒绝策略,最后给出CPU/IO密集型线程数怎么设。

大家好,我是晚安code。

Java线程池这篇,我拖到今天才敢写——不是它难,是它太"讲道理"了。网上讲线程池的文章一抓一大把,但大多上来就甩一张参数表,把人看懵。这篇我换种讲法:从"为什么要池化"讲起,用银行柜台把 7 大参数串起来,最后落到 CPU 密集/IO 密集线程数怎么配。点个收藏,我们开始。

一、线程池就一句话:事先备好,用完归还

程序跑起来,本质就是在占系统资源。其中最烧钱的,就是反复创建、销毁线程——每来一个任务就 new 一个线程,用完就扔,高峰期能把机器内存和上下文切换时间全吃光。线程池解决的,正是这个浪费。

池化技术(Pooling):一种资源管理思想——事先准备好一批资源放在"池子"里,有人要用就来拿,用完再还回去,避免反复创建和销毁。你可以理解为「公共洗衣房,机器随取随用,用完整理好放回」。

线程池(Thread Pool):池化技术在并发上的落地,提前创建一批线程复用,同时控制最大并发数、统一管理线程。创建、调度、回收这些脏活累活,它全包了。

好处就三条:降低资源消耗(线程复用,不反复建)、提高响应速度(线程现成,来了就能干活)、方便管理(并发数可控,出问题好排查)。

资源用之前借、用完还,循环往复,这就是池化

二、先别背参数:Executors 三大方法

Java 里创建线程池最省事的入口是 Executors 工具类,就三个常用方法(2026 年 8 月基于 JDK 8+ 验证):

// 单线程池:串行执行,像只有一个柜员的银行
ExecutorService pool1 = Executors.newSingleThreadExecutor();

// 固定大小:始终只有 5 个线程,超出进队列排队
ExecutorService pool2 = Executors.newFixedThreadPool(5);

// 可伸缩:遇强则强、遇弱则弱,没人用时线程自动回收
ExecutorService pool3 = Executors.newCachedThreadPool();

问题来了:这三个方法看着简单,生产环境却不建议用——因为它们把 7 大参数全藏起来了。newFixedThreadPool 的队列默认容量是 Integer.MAX_VALUE,请求一多任务全堆进队列,内存直接被撑爆 OOM;newCachedThreadPool 的线程数上限同样是 Integer.MAX_VALUE,并发一冲线程多到飞起,一样 OOM。阿里 Java 开发手册干脆把它写进了强制规范:线程池不允许用 Executors 创建。

我第一次跑出这种 OOM 时,就是这种表情。

可能有人会问:Executors 是不是完全不能用?

不至于。本地 demo、低并发的内部工具,图省事用它没问题;但凡接口要扛线上流量,老老实实手动配 ThreadPoolExecutor,就这。

三、手动创建线程池:7 大参数逐个拆

手动创建线程池,用的就是 ThreadPoolExecutor。它构造器里有 7 个参数,每一个都有明确含义:

ThreadPoolExecutor:JDK 并发包里最核心的线程池实现类,Java 里所有线程池创建方式最终都落在它身上。你可以理解为「线程池的总阀门」。

public ThreadPoolExecutor(
        int corePoolSize,                  // 核心线程数
        int maximumPoolSize,               // 最大线程数
        long keepAliveTime,                // 空闲线程存活时间
        TimeUnit unit,                     // 存活时间的单位
        BlockingQueue<Runnable> workQueue, // 阻塞队列
        ThreadFactory threadFactory,       // 线程工厂
        RejectedExecutionHandler handler)  // 拒绝策略

这 7 个参数看着抽象,用一个场景就全活了——银行办业务:

  • 核心线程数 = 常驻柜台窗口,开门就上班
  • 最大线程数 = 最多能开几个窗口(含临时加开的)
  • 阻塞队列 = 候客区,窗口全忙时进来排队
  • 空闲存活时间 = 临时窗口闲太久就撤掉
  • 线程工厂 = 给线程起名、定属性,一般不用动
  • 拒绝策略 = 大堂都满了,再来人怎么办

阻塞队列(BlockingQueue):线程池用来暂存"来不及处理"的任务的队列,窗口全忙时任务先在这儿排队,队列满了才走后面的分支。你可以理解为银行的「候客区」。

窗口是核心线程、候客区是阻塞队列、满员是拒绝策略

来看任务提交后的完整流转(图 1):

Java线程池执行任务流程图:核心线程、阻塞队列、最大线程数、拒绝策略四段判断

流程就一句:核心线程忙 → 进队列排队 → 队列满且线程数没到上限 → 开临时线程 → 全满了 → 走拒绝策略

现在动手配一个,数字故意调小,方便看清每一段:

ExecutorService pool = new ThreadPoolExecutor(
        2,                           // 核心线程 2 个
        5,                           // 最大线程 5 个
        3, TimeUnit.SECONDS,         // 空闲 3 秒回收
        new ArrayBlockingQueue<>(3), // 队列容量 3
        Executors.defaultThreadFactory(),
        new ThreadPoolExecutor.AbortPolicy());

// 最大承载 = 队列 3 + 最大线程 5 = 8
// 提交 9 个任务,第 9 个会触发拒绝策略
for (int i = 1; i <= 9; i++) {
   
    pool.execute(() -> System.out.println(Thread.currentThread().getName() + " OK"));
}
pool.shutdown();

我第一次跑这段时,盯着"线程名 + OK"看了好一会儿才看懂:前 2 个任务走核心线程,第 3~5 个进队列排队,第 6~8 个开临时线程,第 9 个直接被拒。

四、线程池满了怎么办:4 种拒绝策略

拒绝策略不是越狠越好,选错了,会在最忙的时候悄悄丢任务。

拒绝策略(RejectedExecutionHandler):线程池满载(队列和最大线程都到顶)时,对"加塞不进来的任务"的处理方案。你可以理解为银行的「满员处理流程」。

四种策略,两种"硬",两种"软":

  1. AbortPolicy(默认):直接抛 RejectedExecutionException,任务丢了,但你会立刻知道
  2. CallerRunsPolicy:谁提交的,谁自己拿回去跑,不丢任务,但提交方会被拖慢
  3. DiscardPolicy:静默丢弃新任务,不抛异常,最危险——丢了没声音
  4. DiscardOldestPolicy:把队列里排最久的那条挤掉,让新任务进来
策略 行为 会丢任务吗 适合场景
AbortPolicy 直接抛异常 默认;宁可报错也不静默丢
CallerRunsPolicy 提交方自己跑 不想丢任务、能接受变慢
DiscardPolicy 静默丢新任务 能容忍丢,但尽量别用
DiscardOldestPolicy 丢最老的任务 任务越新越重要时

我最开始以为"不抛异常就是好的",其实恰恰相反——静默丢弃会在线上最忙的时候悄悄丢单,等对账才发现。想到这个场景,血压就上来了。

Abort 吼一声、CallerRuns 自己扛、Discard 假装无事、Oldest 挤掉最老的

选策略的核心就一条:能不能接受丢任务,以及丢了要不要有声音。求稳选 CallerRunsPolicy,宁可慢不丢单;省事就接受默认的 AbortPolicy,让异常替你把问题喊出来。

五、最大线程数设多少:CPU 密集 vs IO 密集

最后一个高频问题:核心线程数和最大线程数到底填多少?没有标准答案,但判断标准就一条——看任务是 CPU 吃得多,还是 IO 等得多。

  • CPU 密集型:任务在拼命算,线程数设成 CPU 核数最合适,多了反而来回切换更慢
  • IO 密集型:任务一大半时间在等(等网络、等磁盘),可以让线程数翻倍,用"等"的时间多干活
// 拿到本机 CPU 核数,它是 CPU 密集型的参考基准
int cores = Runtime.getRuntime().availableProcessors();
// CPU 密集型:核心线程数 ≈ cores
// IO 密集型:核心线程数 ≈ cores * 2 起,压测再微调
类型 特点 线程数建议
CPU 密集 计算为主,几乎不等待 核数 cores
IO 密集 等网络/磁盘为主 cores * 2 左右起,再实测调

IO 密集这个"乘 2"只是起点。我今天的笔记里就写了:程序里 15 个大型任务一大半都在等 IO,线程数就该按"等待时间 / 干活时间"的比例往上加,配完用压测说话。没有标准答案,只能自己试。


好了,Java线程池这一块算是啃完了。它不神秘,就是"事先备好、用完归还"八个字,外加 7 大参数这一整套"银行系统"。生产环境记住一条:别用 Executors,自己配 ThreadPoolExecutor——参数看得见,心里才有底。

可能有人会问:线程池用完一定要 shutdown 吗?

要。非守护线程不关闭,JVM 就不会退出,进程会一直挂着。程序结束前记得 shutdown(),不然会莫名其妙发现进程杀不掉。

参考与说明

  • 本文在 Java线程池主题上结合个人学习笔记独立撰写。
  • 涉及 JDK 源码与参数以官方文档为准;示例代码基于 JDK 8+(2026 年 8 月验证)。

我是晚安code,持续分享编程干货。觉得有用的话记得点赞收藏和关注~也欢迎在评论区聊聊:你用 Executors 还是手动配 ThreadPoolExecutor?配线程池踩过哪些坑?

目录
相关文章
|
6天前
|
存储 弹性计算 缓存
阿里云服务器租赁费用:新版租赁收费标准及活动报价参考
本文更新了2026年阿里云全系列云服务器租赁活动报价,所有特惠资源均可前往阿里云活动中心选购,整体覆盖从个人入门到企业级高性能场景的全梯度需求。其中轻量应用服务器主打极致性价比,2核2G峰值200M带宽配置每日10点、15点限时抢购价仅38元/年,2核4G配置379元/年起;高性价比的经济型e实例、通用算力型u2i实例覆盖2核4G至4核32G全档位,适配开发测试与中小型企业业务;搭载英特尔至强6处理器的第九代c9i企业级实例算力较上代提升20%,支撑高并发生产环境,不同实例规格价差清晰,用户可根据自身业务负载与预算灵活选型。
1616 116
|
7天前
|
人工智能 程序员 API
Codex 接入 DeepSeek-V4-Flash:还能补上识图,提供两套方案
Codex 接入 DeepSeek-V4-Flash 怎么配?本文覆盖 CLI 与桌面端,再用 qwen3-vl-flash 补识图,两套方案可直接照做
1096 5
|
13天前
|
云安全 人工智能 运维
阿里云联动百位企业安全专家,共识Agent防御最佳实践
当Agent成为新员工,你的安全边界在哪里?
1954 9
阿里云联动百位企业安全专家,共识Agent防御最佳实践
|
7天前
|
编解码 人工智能 安全
2核4G/4核8G/8核16G阿里云服务器如何选择实例?经济型e、通用算力型u2i与计算型c9i选哪个?
本文介绍了阿里云2核4G、4核8G、8核16G三档主流配置下经济型e、通用算力型u2i和计算型c9i三种实例的最新活动价格与适用场景。同配置下三者价差显著,以2核4G为例,经济型e低至599.93元/年,计算型c9i则高达1742.08元/年。文章详细解析了各实例的性能定位:经济型e适合轻负载入门场景,u2i兼顾稳定算力与性价比,c9i凭借第9代至强处理器与芯片级安全能力支撑高性能业务。同时提示用户可叠加满减优惠券享受折上折,建议根据业务负载与预算综合决策。
538 112
|
19天前
|
人工智能 前端开发 Linux
Codex 桌面版安装 + CC Switch 接入第三方 API 完整教程(2026 最新)
2026最新教程:手把手教你安装Codex桌面版,通过CC Switch v3.17.0一键接入Fenno等国产API(兼容OpenAI Responses格式),跳过账号登录,完整启用代码审查、多步任务与上下文感知功能。零基础友好,全程图文实操。(239字)
2745 4
|
11天前
|
存储 人工智能 关系型数据库
阿里云AI产品与云产品最新组合套餐:Token Plan、AI coding及云服务器和建站等组合优惠价
阿里云推出全新“算力+模型+应用”一站式云与AI组合套餐活动,覆盖从个人开发者到中大型企业的全场景需求。核心亮点为分三档定价的Token Plan订阅服务,支持Qwen3.8-Max-Preview大模型调用,错峰时段最低可享0.2折优惠。活动同步推出AI Coding、智能体部署、云电脑托管、0代码建站等十余类场景化组合,搭配99元/年的普惠云服务器、88元/年的入门数据库等经典特惠产品,还为企业提供1V1定制化AI转型方案,大幅降低了不同用户群体拥抱AI的技术门槛与采购成本。
730 111
|
21天前
|
人工智能 JSON 安全
Fastjson远程代码执行漏洞,阿里云AI安全为您保驾护航
阿里云AI安全产品联动防御Fastjson攻击
2652 13
Fastjson远程代码执行漏洞,阿里云AI安全为您保驾护航
|
7天前
|
人工智能 JSON Shell
2026AI漫剧本地全开源方案(附各个软件模型链接),8G显卡也能流畅运行
这是一套完全本地化部署的AI漫剧生成技术链路:涵盖LLM剧本分镜生成、FLUX文生图(IP-Adapter人脸锁定)、StoryDiffusion时序连贯控制、LTX-2.3唇形同步视频生成,及ComfyUI全流程调度。零云端费用,仅耗硬件算力,单集2–4小时可产出竖屏短视频,适配抖音/B站分发。
|
5天前
|
人工智能 API 开发工具
2026 零基础本地 AI 漫剧完整实操教程(8G 笔记本显卡可用|附可直接复制命令与代码)
本方案提供完全离线、本地运行的漫剧全自动制作流程:RTX3060/4050 8G显卡即可驱动,涵盖Qwen写分镜→ComfyUI统一角色绘图→LTX2.3图生微动画→Qwen3-TTS本地配音→FFmpeg自动合成,全程无水印、免API、不限次。专为低显存优化,解决变脸、闪烁、爆内存三大痛点。(239字)

热门文章

最新文章