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

线程池线程数如何设置

在实际工作和面试中,线程池线程个数的设置是一个常见而又复杂的问题。我们通常在资料中找到一些经典的回答,例如判断任务是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接口的响应时间也会有所不同。

如何设置线程数?

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

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

相关推荐
找了一圈尾巴1 分钟前
Wend看源码-Java-集合学习(List)
java·学习
无名之逆2 分钟前
lombok-macros
开发语言·windows·后端·算法·面试·rust·大学期末
逊嘘21 分钟前
【Java数据结构】链表相关的算法
java·数据结构·链表
爱编程的小新☆22 分钟前
不良人系列-复兴数据结构(二叉树)
java·数据结构·学习·二叉树
m0_7482478025 分钟前
SpringBoot集成Flowable
java·spring boot·后端
小娄写码35 分钟前
线程池原理
java·开发语言·jvm
散一世繁华,颠半世琉璃36 分钟前
SpringBoot揭秘:URL与HTTP方法如何定位到Controller
spring boot·后端·http
安晴晚风2 小时前
从0开始在linux服务器上部署SpringBoot和Vue
linux·运维·前端·数据库·后端·运维开发
陌上花开࿈5 小时前
调用第三方接口
java
Aileen_0v06 小时前
【玩转OCR | 腾讯云智能结构化OCR在图像增强与发票识别中的应用实践】
android·java·人工智能·云计算·ocr·腾讯云·玩转腾讯云ocr