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

线程池线程数如何设置

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

如何设置线程数?

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

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

相关推荐
追逐时光者33 分钟前
一款使用 C# 编写专为 Windows 11 打造的文件资源管理器增强工具!
后端·.net
风象南1 小时前
普通人用AI加持赚到的第一个100块
人工智能·后端
皮皮林5512 小时前
Java性能调优黑科技!1行代码实现毫秒级耗时追踪,效率飙升300%!
java
冰_河3 小时前
QPS从300到3100:我靠一行代码让接口性能暴涨10倍,系统性能原地起飞!!
java·后端·性能优化
JavaGuide5 小时前
7 道 RAG 基础概念知识点/面试题总结
前端·后端
桦说编程6 小时前
从 ForkJoinPool 的 Compensate 看并发框架的线程补偿思想
java·后端·源码阅读
格砸6 小时前
从入门到辞职|从ChatGPT到OpenClaw,跟上智能时代的进化
前端·人工智能·后端
蝎子莱莱爱打怪7 小时前
GitLab CI/CD + Docker Registry + K8s 部署完整实战指南
后端·docker·kubernetes
躺平大鹅7 小时前
Java面向对象入门(类与对象,新手秒懂)
java