根据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网络通信(线程池和线程池版本的服务器代码)
线程池 介绍 线程池: 一种线程使用模式.线程过多会带来调度开销,进而影响缓存局部性和整体性能.而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务.这避免了在处理短时间任务时创建与销毁线程的 ...
随机推荐
- 依靠MySQL(frm、MYD、MYI)数据文件恢复
该方法并不是适用于所有MySQL数据库 此次恢复是朋友那边的数据查不了了,请求我支援,出于各种心理原因,我答应试试,于是就有了这篇文章和这次经历,废话不多说.... 物理条件:宿机是Ubuntu16. ...
- IEnumerable和IQueryable口的区别
IQueryable: 动态表达式树拼接查询语句,把拼接后查询语句进行执行:Execute触发,延迟加载IEnumerable:对内存中的数据,动态拼接查询语句,进行查询:ToList触发,延迟加载: ...
- Flutter 的异步机制Future
Dart是一个单线程语言,可以理解成物理线路中的串联,当其遇到有延迟的运算(比如IO操作.延时执行)时,线程中按顺序执行的运算就会阻塞,用户就会感觉到卡顿,于是通常用异步处理来解决这个问题. Dart ...
- HttpHelper帮助类
public class HttpHelper { #region 预定义方变量 //默认的编码 private Encoding _encoding = Encoding.Default; //Po ...
- nssm设置solr开机启动服务
首先,下载nssm http://www.nssm.cc/download 命令 nssm install solr 然后到服务里启动solr,并设置为自动 Ctrl+Shift+Esc(说明:Esc ...
- 洛谷 题解 P2802 【回家】
思路:DFS+剪枝 本题可以用一个字符二维数组来存整个地图,然后在往四个方向进行搜索.注意:当走到家门前要先判断血量!(本人就被坑了) 代码: #include<bits/stdc++.h> ...
- SQLSever语句(增、删、改、查)一、增:有4种方法1.使用insert插入单行数据
SQL语句(增.删.改.查) 一.增:有4种方法 1.使用insert插入单行数据: 语法:insert [into] <表名> [列名] values <列值> 例:inse ...
- pycharm配置git版本管理
1.下载并安装git 首先你电脑必须安装git版本控制器(软件),在官网下载即可 2.安装git,正常安装即可 编缉器的选择,根据电脑实际情况选择合适的编缉器 安装参考:https://www.cnb ...
- NOIP 2018 提高组初赛试题 题目+答案+简要解析
一.单项选择题(共 10 题,每题 2 分,共计 20 分: 每题有且仅有一个正确选项) 1. 下列四个不同进制的数中,与其它三项数值上不相等的是( ). A. (269) 16 B ...
- mysql innodb数据库损坏导致无法启动
生产环境中的mysql突然启动不了,查了原因是innodb库错误,以前就遇到过这个问题,稀里糊涂的没解决,结果导致大量数据丢失.这些又遇到这个问题,果断把那个有问题的数据库移动了别的地方,启动了mys ...