如何区分IO/CPU 密集型,线程池核心参数怎么设置

  1. CPU 密集型 :任务大量消耗 CPU,几乎无等待。 核心思路:减少线程数量,减少上下文切换

核心公式:核心线程数 = CPU核心数 + 1

+1 是为了防止某个线程偶尔页缺失 / 临时暂停,让这个备用线程顶上去,充分利用 CPU。

  1. IO 密集型 :任务大部分时间在等待网络、数据库、文件 IO,CPU 空闲。 核心思路:多开线程,利用等待时间处理别的任务

核心公式:核心线程数 = CPU核心数 * (1 + IO等待时间 / CPU计算时间)

经验估算简化:2 * CPU核心数,业务 IO 阻塞严重时可以给到CPU 核心数 * 5~10,根据压测调优。
⚠️ 重点:公式只是理论参考!最终一定要压测调整,不能直接硬套。

详细解释

1. CPU 密集型

  • 特点:大量计算,几乎没有 IO 等待,CPU 一直在跑。
  • 如果线程开太多:多个线程频繁抢占 CPU,上下文切换开销很大,性能下降
  • 推荐:核心线程数 ≈ CPU 核心数 +1
  • 例子:4 核 CPU,核心线程设置为 5。

2. IO 密集型(后端开发最常见,数据库、RPC、文件读写)

  • 特点:线程大部分时间阻塞等待 IO,CPU 是空闲的。
  • 线程多一点没关系,当一个线程等待 DB 返回,其他线程可以继续执行。
  • 公式理解:IO等待时间 / CPU计算时间 是等待占比。 比如:任务执行总共 1000ms,其中计算 100ms,等待 DB900ms。 CPU核心数*(1+900/100)= 核心数*10
  • 经验值:一般 2 倍 CPU 核心起步;IO 阻塞很高,可放大到 5~10 倍,但是不能无限大,线程太多会占用大量内存,数据库连接池、连接数也会打满,造成雪崩。

相关问题

Q:为什么 IO 密集不能无限加大线程?

A:线程本身占用内存;线程过多,操作系统上下文切换开销上升;同时下游资源(数据库连接、第三方接口)都有最大连接上限,线程太多会把下游打垮。

Q:线程池的核心参数有哪些?

ThreadPoolExecutor 7 个参数:

  1. corePoolSize:核心线程数
  2. maximumPoolSize:最大线程数
  3. keepAliveTime:非核心线程空闲存活时间
  4. unit:时间单位
  5. workQueue:阻塞队列,存放等待任务
  6. threadFactory:线程工厂,创建线程
  7. handler:拒绝策略,任务满了之后的处理策略

Q:四种拒绝策略?

  1. AbortPolicy:抛异常(默认)
  2. DiscardPolicy:直接丢弃任务,不抛异常
  3. DiscardOldestPolicy:丢弃队列最老任务,再尝试提交
  4. CallerRunsPolicy:交给调用者线程执行(不会丢任务,降级)

一句话总结

CPU 密集型,核心线程数设置为 CPU 核心数 + 1,减少上下文切换;

IO 密集型可以设置更大,参考CPU核心*(1+IO等待时间/计算时间),经验值 2~10 倍 CPU 核心;

公式仅理论,最终必须压测验证。

相关推荐
JAVA面经实录9172 小时前
IDEA 开发知识
java·intellij-idea·idea
于樱花森上飞舞2 小时前
【Redis】哨兵详解
java·开发语言·数据库·redis
2601_953824613 小时前
基于SSM的水果超市管理系统
java·tomcat·maven
guo_wen_qiang3 小时前
springboot如何自定义一个启动器starter
java·spring boot·intellij-idea
许彰午3 小时前
55-字典缓存与通知SPI
java·低代码·架构
captain3763 小时前
HTTP(2)
java·网络·http·java-ee
徐子童3 小时前
介绍MVCC机制
java·mysql·面试题·秋招·并发·mvcc
Wang's Blog3 小时前
Java 项目实战: 外卖平台-启用禁用员工账号与Long精度丢失修复
java·服务器
乌暮3 小时前
Java 抽象类与接口详解:半成品图纸 vs 能力合同
java·开发语言·后端·学习