10 | Java线程(中):创建多少线程才是合适的?
王宝令
该思维导图由 AI 生成,仅供参考
在 Java 领域,实现并发程序的主要手段就是多线程,使用多线程还是比较简单的,但是使用多少个线程却是个困难的问题。工作中,经常有人问,“各种线程池的线程数量调整成多少是合适的?”或者“Tomcat 的线程数、Jdbc 连接池的连接数是多少?”等等。那我们应该如何设置合适的线程数呢?
要解决这个问题,首先要分析以下两个问题:
为什么要使用多线程?
多线程的应用场景有哪些?
为什么要使用多线程?
使用多线程,本质上就是提升程序性能。不过此刻谈到的性能,可能在你脑海里还是比较笼统的,基本上就是快、快、快,这种无法度量的感性认识很不科学,所以在提升性能之前,首要问题是:如何度量性能。
度量性能的指标有很多,但是有两个指标是最核心的,它们就是延迟和吞吐量。延迟指的是发出请求到收到响应这个过程的时间;延迟越短,意味着程序执行得越快,性能也就越好。 吞吐量指的是在单位时间内能处理请求的数量;吞吐量越大,意味着程序能处理的请求越多,性能也就越好。这两个指标内部有一定的联系(同等条件下,延迟越短,吞吐量越大),但是由于它们隶属不同的维度(一个是时间维度,一个是空间维度),并不能互相转换。
我们所谓提升性能,从度量的角度,主要是降低延迟,提高吞吐量。这也是我们使用多线程的主要目的。那我们该怎么降低延迟,提高吞吐量呢?这个就要从多线程的应用场景说起了。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
本文从性能度量的角度出发,介绍了多线程的应用场景和最佳线程数的计算方法。文章首先强调了性能度量的核心指标是延迟和吞吐量,解释了为什么要使用多线程。接着详细阐述了多线程的应用场景,包括优化算法和提高硬件利用率。针对CPU密集型和I/O密集型计算场景,提出了最佳线程数的计算方法。对于CPU密集型计算,最佳线程数为CPU核数加一;而对于I/O密集型计算,最佳线程数与程序中CPU计算和I/O操作的耗时比相关。最后总结了将硬件性能发挥到极致的原则,并强调了在工程上需要估算关键参数并进行压测验证。整体而言,本文通过理论分析和实际应用,为读者提供了创建合适线程数的指导原则。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Java 并发编程实战》,新⼈⾸单¥59
《Java 并发编程实战》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(132)
- 最新
- 精选
- 假行僧个人觉得公式话性能问题有些不妥,定性的io密集或者cpu密集很难在定量的维度上反应出性能瓶颈,而且公式上忽略了线程数增加带来的cpu消耗,性能优化还是要定量比较好,这样不会盲目,比如io已经成为了瓶颈,增加线程或许带来不了性能提升,这个时候是不是可以考虑用cpu换取带宽,压缩数据,或者逻辑上少发送一些。最后一个问题,我的答案是大部分应用环境是合理的,老师也说了是积累了一些调优经验后给出的方案,没有特殊需求,初始值我会选大家都在用伪标准
作者回复: 👍👍
2019-03-21575 - 多拉格·five问一下老师,这个线程配置比我在其他的资料也看过,但是最后那个公式没见过,方便说一下如何测试IO/CPU 这个耗时比例吗
作者回复: 比较简单的工具就是apm了
2019-03-21353 - aksonic早起的鸟果然有食吃,抢到了顶楼,哈哈。 对于老师的思考题,我觉得不合理,本来就是分CPU密集型和IO密集型的,尤其是IO密集型更是需要进行测试和分析而得到结果,差别很大,比如IO/CPU的比率很大,比如10倍,2核,较佳配置:2*(1+10)=22个线程,而2*CPU核数+1 = 5,这两个差别就很大了。老师,我说的对不对?
作者回复: 不但起的早,还看懂了
2019-03-2146 - 董宗磊思考题:认为不合理,不能只考虑经验,还有根据是IO密集型或者是CPU密集型,具体问题具体分析。 看今天文章内容,分享个实际问题;我们公司服务器都是容器,一个物理机分出好多容器,有个哥们设置线程池数量直接就是:Runtime.getRuntime().availableProcessors() * 2;本来想获取容器的CPU数量 * 2,其实Runtime.getRuntime().availableProcessors()获取到的是物理机CPU合数,一下开启了好多线程 ^_^
作者回复: 新版的jvm开始支持docker了,老版本问题还挺多
2019-03-21242 - 南山理论加经验加实际场景,比如现在大多数公司的系统是以服务的形式来通过docker部署的,每个docker服务其实对应部署的就一个服务,这样的情况下是可以按照理论为基础,再加上实际情况来设置线程池大小的,当然通过各种监控来调整是最好的,但是实际情况是但服务几十上百,除非是核心功能,否则很难通过监控指标来调整线程池大小。理论加经验起码不会让设置跑偏太多,还有就是服务中的各种线程池统一管理是很有必要的
作者回复: 说的太对了!!!
2019-03-3131 - 探索无止境老师早上好,当应用来的请数量过大,此时线程池的线程已经不够使用,排队的队列也已经满了,那么后面的请求就会被丢弃掉,如果这是一个更新数据的请求操作,那么就会出现数据更新丢失,老师有没有什么具体的解决思路?期待解答
作者回复: 单机有瓶颈,就分布式。 数据库有瓶颈,就分库分表分片
2019-03-21718 - 木卫六在4核8线程的处理器使用Runtime.availableProcessors()结果是8,超线程技术属于硬件层面上的并发,从cpu硬件来看是一个物理核心有两个逻辑核心,但因为缓存、执行资源等存在共享和竞争,所以两个核心并不能并行工作。超线程技术统计性能提升大概是30%左右,并不是100%。另外,不管设置成4还是8,现代操作系统层面的调度应该是按逻辑核心数,也就是8来调度的(除非禁用超线程技术)。所以我觉得这种情况下,严格来说,4和8都不一定是合适的,具体情况还是要根据应用性能和资源的使用情况进行调整。这是个人的理解,请老师指正。
作者回复: 工作中都是按照逻辑核数来的,理论值和经验值只是提供个指导,实际上还是要靠压测。
2019-03-2216 - QQ怪我就想问下如何测试io耗时和cpu耗时
作者回复: apm工具可以
2019-03-2111 - zsh0103请问老师, 1 在现实项目如何计算I/O耗时与CPU耗时呢,比如程序是读取网络数据,然后分析,最后插入数据库。这里网络读取何数据库插入是两次IO操作,计算IO耗时是两次的和吗? 2. 如果我在一台机器上部署2个服务,那计算线程数是要每个服务各占一半的数量吗? 3. 如果我用一个8核CPU的机器部署服务,启动8个不同端口的相同服务,和启动一个包含8个线程的服务在处理性能上会有区别吗?
作者回复: 1.两次之和 2.理论值仅仅适用部署一个服务的场景。 3.有区别
2019-03-217 - 已忘二老师,有个疑问,就是那个I/O和CPU比为2:1时,CPU使用率达到了100%,但是I/O使用率却到了200%,也就是时刻有两个I/O同时执行,这样是可以的么?I/O不需要等待的么?
作者回复: io有瓶颈后,cpu使用率就上不去了
2019-03-21106
收起评论