业务程序中如何设置线程数?

线程池线程数如何设置

在实际工作和面试中,线程池线程个数的设置是一个常见而又复杂的问题。我们通常在资料中找到一些经典的回答,例如判断任务是CPU密集型还是IO密集型,或者参考《Java并发编程实战》一书的建议:

1.判断任务是CPU密集型还是IO密集型(其中N表示CPU的核心数量):

  • CPU密集型,线程池大小设置为N+1。
  • IO密集型,线程池大小设置为2N+1。

然而,在实际业务中,任务往往涉及到复杂的计算和等待操作,而且一个服务通常不仅执行单一任务。

2.《Java并发编程实战》的推荐设置:

  • Ncpu表示CPU的数量。
  • Ucpu表示期望的CPU的使用率。
  • W/C表示等待时间与计算时间的比例。

比如说我们通过监控判断接口CPU计算时间是20ms,等待时间是80ms,期望CPU使用率是80%,那么根据公式得出:

线程数=CPU个数8*CPU使用率0.8*(1+(等待时间80ms/计算时间20ms))=32

在实际应用中,由于业务场景的复杂性,一个服务可能涉及多种操作,包括内存读写、计算、I/O等。因此,仅仅通过公式计算线程数可能过于理想化。当我们这样回答时,面试官显然是不会满意的。

业务程序中如何量化线程数?

此时项目中需要一个业务场景的多线程(或者线程池)来异步/并行执行业务流程。

以一个常规的接口处理为例,可能涉及以下流程:

sequenceDiagram participant Client participant Server participant Cache participant RPC participant DB Client->>+Server: 发起请求 Server->>+Server: 1、参数解析、参数校验 Server->>+Cache: 2、缓存查询数据 Cache-->-Server: return alt 缓存命中 Server-->>-Client: 返回结果 else 缓存未命中 Server->>+DB: 3、调用数据库查询数据 DB -->-Server: return Server->>+RPC: 4、调用RPC接口查询数据 RPC -->-Server: return Server->>+Server: 5、业务逻辑本地计算处理 Server->>+Cache: 6、更新缓存 Cache-->-Server: return Server->>+Server: 7、参数组装 Server-->>-Client: 返回结果 end

该接口涉及以下步骤:

  1. 参数解析、参数校验
  2. 缓存查询数据,如果查询到直接返回了
  3. 如果缓存没查到数据,调用数据库查询数据
  4. 调用RPC接口查询数据
  5. 业务逻辑本地计算处理
  6. 将计算后的数据更新到缓存
  7. 最后进行参数组装并返回

这个接口中,步骤2、3、4、6都涉及IO等待,其余步骤会涉及CPU计算。需要注意的是步骤2查询到缓存后直接返回了,不会执行后面的流程。

线程数计算误区

如果我们按照上面的公式来规划线程数的话,误差一定会很大。

做业务开发时,我们通常选择SpringBoot作为基础框架,使用Tomcat容器、druid连接池、并采用G1垃圾回收器。

在设置线程数时,我们常常受到误导。例如,一个主机上可能不仅部署了一个进程,一个进程中还有许多运行中的线程,同时druidJVMG1也都有各自的线程池和后台线程。这些线程都在当前进程、当前主机上运行,也占用CPU资源。

此外,CPU执行时会涉及CPU时间片轮转和线程切换,而高峰期数据库和RPC接口的响应时间也会有所不同。

如何设置线程数?

那么到底如何设置线程数呢?这个没有标准答案,我们一定要结合场景,跟面试官讲清楚。最好通过公式初步设置一个大概值,然后通过测试去找到一个最合适的线程数。同时,线程池最好支持动态调整,这样即时有问题,我们也能灵活的进行调整。

这样的解释能够更好地向面试官传达我们对于线程数设置的理解和灵活应对业务复杂性的能力。

相关推荐
晴殇i4 分钟前
【前端缓存】localStorage 是同步还是异步的?为什么?
前端·面试
Elieal8 分钟前
SpringBoot 数据层开发与企业信息管理系统实战
java·spring boot·后端
识君啊8 分钟前
MyBatis-Plus 逻辑删除导致唯一索引冲突的解决方案
java·spring boot·mybatis·mybatis-plus·唯一索引·逻辑删除
Coder_Boy_9 分钟前
Java开发者破局指南:跳出内卷,借AI赋能,搭建系统化知识体系
java·开发语言·人工智能·spring boot·后端·spring
QT.qtqtqtqtqt11 分钟前
SQL注入漏洞
java·服务器·sql·安全
独自破碎E14 分钟前
BISHI23 小红书推荐系统
java·后端·struts
xqqxqxxq16 分钟前
Java IO 核心:BufferedReader/BufferedWriter & PrintStream/PrintWriter 技术笔记
java·笔记·php
Aric_Jones17 分钟前
idea使用.env运行SpringBoot项目
java·spring boot·intellij-idea
gustt19 分钟前
构建全栈AI应用:集成Ollama开源大模型
前端·后端·ollama
刘一说24 分钟前
Java 中实现多租户架构:数据隔离策略与实践指南
java·oracle·架构