根据CPU核心数确定线程池并发线程数(转)
一、抛出问题
关于如何计算并发线程数,一般分两派,来自两本书,且都是好书,到底哪个是对的?问题追踪后,整理如下:
第一派:《Java Concurrency in Practice》即《java并发编程实践》,如下图:
如上图,在《Java Concurrency in Practice》一书中,给出了估算线程池大小的公式:
Nthreads=Ncpu*Ucpu*(1+w/c),其中
Ncpu=CPU核心数
Ucpu=cpu使用率,0~1
W/C=等待时间与计算时间的比率
第二派:《Programming Concurrency on the JVM Mastering》即《Java 虚拟机并发编程》
线程数=Ncpu/(1-阻塞系数)
二、分析
对于派系一,假设cpu100%运转,即撇开CPU使用率这个因素,线程数=Ncpu*(1+w/c)。
现在假设将派系二的公式等于派系一公式,即Ncpu/(1-阻塞系数)=Ncpu*(1+w/c),===》阻塞系数=w/(w+c),即阻塞系数=阻塞时间/(阻塞时间+计算时间),这个结论在派系二后续中得到应征,如下图:
由此可见,派系一和派系二其实是一个公式......这样我就放心了......
三、实际应用
那么实际使用中并发线程数如何设置呢?分析如下(我们以派系一公式为例):
Nthreads=Ncpu*(1+w/c)
IO密集型:一般情况下,如果存在IO,那么肯定w/c>1(阻塞耗时一般都是计算耗时的很多倍),但是需要考虑系统内存有限(每开启一个线程都需要内存空间),这里需要上服务器测试具体多少个线程数适合(CPU占比、线程数、总耗时、内存消耗)。如果不想去测试,保守点取1即,Nthreads=Ncpu*(1+1)=2Ncpu。这样设置一般都OK。
计算密集型:假设没有等待w=0,则W/C=0. Nthreads=Ncpu。
至此结论就是:
IO密集型=2Ncpu(可以测试后自己控制大小,2Ncpu一般没问题)(常出现于线程中:数据库数据交互、文件上传下载、网络数据传输等等)
计算密集型=Ncpu(常出现于线程中:复杂算法)
java中:Ncpu=Runtime.getRuntime().availableProcessors()
=========================此处可略过=============================================
当然派系一种《Java Concurrency in Practice》还有一种说法,
即对于计算密集型的任务,在拥有N个处理器的系统上,当线程池的大小为N+1时,通常能实现最优的效率。(即使当计算密集型的线程偶尔由于缺失故障或者其他原因而暂停时,这个额外的线程也能确保CPU的时钟周期不会被浪费。)
即,计算密集型=Ncpu+1,但是这种做法导致的多一个cpu上下文切换是否值得,这里不考虑。读者可自己考量。
===============================================================================
四、总结:
选择线程池并发线程数的因素很多:任务类型、内存等线程中使用到所有资源都需要考虑。本文经过对现有文献的分析论证,得出结论,并给出了实际应用公式,实乃工程师之福利,技术之典范......
根据CPU核心数确定线程池并发线程数(转)的更多相关文章
- 转 根据CPU核心数确定线程池并发线程数
转自: https://www.cnblogs.com/dennyzhangdd/p/6909771.html?utm_source=itdadao&utm_medium=referral 目 ...
- 根据CPU核心数确定线程池并发线程数
一.抛出问题 关于如何计算并发线程数,一般分两派,来自两本书,且都是好书,到底哪个是对的?问题追踪后,整理如下: 第一派:<Java Concurrency in Practice>即&l ...
- .NET线程池最大线程数的限制-记一次IIS并发瓶颈
.NET ThreadPool 最大线程数的限制 IIS并发瓶颈,有几个地方,IIS线程池的最大队列数,工作进程数,最大并发数.这些这里就不展开.主要是最近因为过度使用Task 导致的线程数占用过多, ...
- java并发编程(十五)----(线程池)java线程池简介
好的软件设计不建议手动创建和销毁线程.线程的创建和销毁是非常耗 CPU 和内存的,因为这需要 JVM 和操作系统的参与.64位 JVM 默认线程栈是大小1 MB.这就是为什么说在请求频繁时为每个小的请 ...
- 高并发的epoll+线程池,线程池专注实现业务
我们知道,服务器并发模型通常可分为单线程和多线程模型,这里的线程通常是指“I/O线程”,即负责I/O操作,协调分配任务的“管理线程”,而实际的请求和任务通常交由所谓“工作者线程”处理.通常多线程模型下 ...
- java并发编程(十七)----(线程池)java线程池架构和原理
前面我们简单介绍了线程池的使用,但是对于其如何运行我们还不清楚,Executors为我们提供了简单的线程工厂类,但是我们知道ThreadPoolExecutor是线程池的具体实现类.我们先从他开始分析 ...
- Python的并发并行[4] -> 并发[0] -> 利用线程池启动线程
利用线程池启动线程 submit与map启动线程 利用两种方式分别启动线程,同时利用with上下文管理来对线程池进行控制 from concurrent.futures import ThreadPo ...
- 由浅入深理解Java线程池及线程池的如何使用
前言 多线程的异步执行方式,虽然能够最大限度发挥多核计算机的计算能力,但是如果不加控制,反而会对系统造成负担.线程本身也要占用内存空间,大量的线程会占用内存资源并且可能会导致Out of Memory ...
- Linux网络通信(线程池和线程池版本的服务器代码)
线程池 介绍 线程池: 一种线程使用模式.线程过多会带来调度开销,进而影响缓存局部性和整体性能.而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务.这避免了在处理短时间任务时创建与销毁线程的 ...
随机推荐
- 怎么通过原生JS改变元素的class属性
解决方法:document.getElementById('test').className = 'emphasis' Eg: <!doctype html> <html lang= ...
- 类型TTreeView.items.add 与 TTreeView.items.addchild有何区别?(10分)
我看了书上例子,好象两者都可以实现treeview中的node 的构建. addchild是给当前的node建一个子node,它比当前node要向右缩进几格add建立同级的node,不缩进 aNode ...
- GBDT详解例子
https://blog.csdn.net/zpalyq110/article/details/79527653
- Flutter参数的传递和接收
上次只写了方法和参数,这次写了完整的示例,页面间参数的传递和接收的示例. 1.参数传递 用在程序上解释就是比如你进入一个商品选择列表,当你想选择一个商品的具体信息的时候,你就要传递商品编号,详细页面接 ...
- Sed---linux系统三剑客(二)
grep .sed.awk被称为linux中的"三剑客". grep 更适合单纯的查找或匹配文本 sed 更适合编辑匹配到的文本 awk 更适合格式化文本,对文本进行较复杂格式 ...
- 转发表(MAC表)、ARP表、路由表总结
原文:https://cloud.tencent.com/developer/article/1173761 转发表(MAC表).ARP表.路由表总结 我是东东东 发表于我是东东强订阅 1.5K ...
- 【DSP开发】DSP能用VS2010生成的链接库文件吗?
[DSP开发]DSP能用VS2010生成的链接库文件吗? 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:可能这个问题让行家看上去就会莞尔一笑,但是很多 ...
- nssm设置solr开机启动服务
首先,下载nssm http://www.nssm.cc/download 命令 nssm install solr 然后到服务里启动solr,并设置为自动 Ctrl+Shift+Esc(说明:Esc ...
- [转帖] 修改nginx 默认上传文件大小
nginx默认会限制上传文件的大小为1M https://blog.51cto.com/ycgit/1563307 艺晨光关注0人评论12037人阅读2014-10-13 15:29:50 htt ...
- TCP的socket连接
package newtest; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStre ...