当前位置: 首页 > news >正文

线程池核心参数?如何设置?

这句先记住。

线程池核心参数决定了:线程池最多开多少线程?任务怎么排队?线程空闲多久回收?线程怎么创建?满了之后怎么办?

一、线程池 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. 任务来了,先看核心线程满没满

  2. 没满就创建核心线程执行

  3. 满了就放进阻塞队列

  4. 队列满了,再创建非核心线程

  5. 如果线程数也到最大了,就执行拒绝策略

你只要记住这条主线:

先核心线程,再队列,再最大线程,最后拒绝策略。

三、这些参数怎么设置

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 密集型可以适当放大;队列建议用有界队列,避免任务无限堆积;最大线程数根据系统承载能力预留弹性;拒绝策略则要结合业务是否允许降级或丢弃。总体上线程池参数没有固定值,通常要结合业务场景和压测结果来定。

http://www.cnnetsun.cn/news/1287859.html

相关文章:

  • 【八股必备】设计模式+常见技术场景
  • 算法专题--数组二分查找--Leetcode704题
  • ENSP USG6000v Web登录配置全流程详解
  • XSS在线平台实战指南:从创建项目到捕获Cookie
  • 华为云OBS实战配置:从基础创建到高级策略部署
  • Web安全实战:绕过__wakeup漏洞攻防解析
  • 调速器响应,0.05秒级延迟
  • 实战手记:基于STM32F407的SD卡Bootloader开发
  • 3.3 凹凸性与二阶导数判别法
  • 运算符和js语句
  • 提升安卓开发效率:用快马ai一键生成mvvm网络请求框架代码
  • 从零实现卡尔曼滤波:Arduino与MPU6050的传感器数据融合实战
  • 【Windows】Dify + Ollama/Xinference/GPUStack:一站式AI开发环境搭建指南
  • 零基础入门:Sambert多情感语音合成镜像部署指南,3步搭建Web服务
  • 基于Arduino的智能循迹小车设计与PID优化实战
  • 通义千问3-VL-Reranker-8B效果展示:图文视频混合检索,排序精准度实测
  • OpenHD轻量化移植:用Ubuntu笔记本替代树莓派打造低成本高清图传地面站
  • Codeforces Round 1082 (Div. 2) E
  • SpringBoot基于Web的智能家教服务平台
  • NVIDIA Profile Inspector 深度优化指南:从硬件潜力到极致体验
  • 【正点原子I.MX6U-MINI】从零到系统启动:uboot编译与EMMC固化的完整实践
  • 快马平台一键生成Spring Boot用户管理原型,5分钟搭建可运行后端服务
  • 基于立创地文星开发板的USB-Hub电压电流表DIY全解析:硬件选型、软件配置与外壳设计
  • 【数字电子技术课程设计】基于FPGA的高精度数字电子钟设计与实现
  • Allegro17.4异形焊盘实战:从DXF导入到Padstack的完整流程
  • 提升创作效率:用快马平台打造可实时迭代的旗博士口播智能体
  • 如何在遵守协议前提下实现高效内容访问:解锁信息价值的技术方案与合规指南
  • 快马平台五分钟搭建openclaw抓取原型,验证你的数据采集想法
  • 泰山派RK3576开发板Android 14系统ADB调试与投屏实战指南
  • ESP32双模通信实战:从Wi-Fi联网到蓝牙透传的物联网应用