计算密集型 vs IO密集型 线程数设置核心公式来源Java线程池经典经验公式只是经验值线上必须压测调优1、计算密集型CPU-bound特征即CPU密集型。指大量CPU运算自身服务器的CPU经常跑满外部IO等待很少即等待外部资源很少。比如执行的任务为大数据计算、加密解密、算法运算。线程执行主要耗时点耗时主要花在CPU的运算上。理论最优线程数CPU核心数 或 CPU核心数1线程数 ≈ CPU核心数 ~ CPU核心数1原因CPU核心同一时刻只能跑1个线程线程多了会大量上下文切换反而变慢。1是为了应对偶尔线程短暂停顿充分利用CPU。⚠️ 不要开远大于CPU核心数的线程会CPU飙升、吞吐量下降。示例8核CPU线程池设置8 ~ 9。2、IO密集型IO-bound特征外部IO等待多大量等待外部资源自身服务器的CPU经常空闲。执行任务时等待外部资源举例数据库查询、RPC调用、HTTP请求、文件读写、Redis操作。线程执行主要耗时点耗时主要花在等待外部IO返回。因为CPU使用率低因此可以通过适当加大线程数来提高QPS。经典公式线程数 CPU核心数 * (1 平均IO等待时间 / CPU执行时间)等待时间线程阻塞等待IO的时间CPU执行时间真正跑代码消耗CPU的时间。举例子8核机器业务线程执行代码10ms等待DB/RPC 90ms等待/CPU 90/10 9线程数 8 * (19) 80简易经验IO密集型一般设置2*CPU核心数 ~ 几十上百看IO阻塞占比。阻塞占比越高需要的线程数越大。注意不是无限大线程太多会导致内存占用高、上下文切换变多、数据库连接池打满、tcp连接耗尽。简单版类型场景示例推荐线程数经验计算密集算法、加密、大数据运算Ncpu ~ Ncpu1IO密集DB、RPC、HTTP、RedisNcpu *(1 平均IO等待时间 / CPU执行时间)经验2*Ncpu ~ 200以内Ncpu机器CPU逻辑核心数Java中Runtime.getRuntime().availableProcessors()获取。快速判断一个接口属于哪一类看监控请求慢的时候CPU 利用率很高→ 偏向计算密集型请求慢的时候CPU 很低大量线程 WAITING→ IO 密集型计算密集型与IO 密集型的共同点两者都可以是高耗时请求但慢的根源完全不一样。3、Java线程池常见坑不要直接用Executors.newFixedThreadPool无界队列队列堆积会OOM生产用ThreadPoolExecutor手动构造。IO密集场景线程池大了配套资源也要跟上数据库连接池、redis连接池、http连接池否则线程再多也卡在连接。比如线程池开到80mysql连接池至少要给到接近这个数值不然大量线程等待获取数据库连接。区分CPU核心数是逻辑核还是物理核一般JDK拿到的是逻辑核。4、结合业务调优步骤公式只是起点必须压测初始按公式设置压测观察指标CPU利用率计算密集尽量跑到70‑85%IO密集CPU不会很高线程池队列长度队列持续上涨说明线程不够平均响应时间、QPS逐步上调/下调线程数找到QPS最高、RTResponse Time响应时间最低的点。5、业务常见误区IO密集线程开越大越快❌超过阈值后线程越多上下文切换、内存开销上升RT反而恶化。计算密集开很多线程提升速度❌CPU跑满大量线程切换性能暴跌。举个实际例子机器8逻辑核离线计算任务计算密集核心线程8后端web接口大量DBRPCIO密集核心线程30‑60配合合理连接池。小提示SpringBoot内置tomcat就是IO密集场景默认最大线程200也是这个思路。