深入理解-CPU核心数与线程池并发线程数关系
那是一个风和日丽的下午!
面试官微微一笑,对我说:“小伙子,合理配置线程池你是如何考虑的?”
我微微一笑,说出了我的答案:
首先确认业务是CPU密集型还是IO密集型的,
如果是CPU密集型的,那么就应该尽量少的线程数量,一般为CPU的核数+1;
如果是IO密集型:所以可多分配一点 cpu核数*2 也可以使用公式:CPU 核数 / (1 - 阻塞系数);其中阻塞系数在 0.8 ~ 0.9 之间。
面试官心想,有点东西,接着追问:“那你是如何得到的这个公式,或者说你是如何根据CPU核心数确定线程池并发线程数的”
我心想这不是小瞧我嘛?不屑回答的我脱下了我的帽子
哈哈哈哈,进入正题!
1,追书溯源
关于如何计算并发的线程数量,一般分两派,来自两本书,且都是好书,
第一派:《Java Concurrency in Practice》即《java并发编程实践》,我们简称A派。
第二派:《Programming Concurrency on the JVM Mastering》即《Java 虚拟机并发编程》,我们简称B派。
到底哪个是对的?我们截取书中部分内容具体看看。
A派一书中是这样写的
B派一书中是这样写的
2,大胆分析
对于A派,假设CPU跑满,即撇开CPU使用率这个因素,A派认为 线程数 = Ncpu * ( 1 + w/c )
大胆假设将B派的公式等于A派公式,
即 Ncpu / (1-阻塞系数) = Ncpu * ( 1 + w/c ) 即 阻塞系数 = 阻塞时间 /(阻塞时间+计算时间),
这个结论在派系二后续中得到应征,如下图:
3,实际运用
那么实际使用中并发线程数如何设置呢?分析如下(我们以A派公式为例):
Nthreads = Ncpu * (1+w/c)
IO密集型:一般情况下,如果存在IO,那么肯定w/c>1(阻塞耗时一般都是计算耗时的很多倍),但是需要考虑系统内存有限(每开启一个线程都需要内存空间),这里需要上服务器测试具体多少个线程数适合(CPU占比、线程数、总耗时、内存消耗)。
如果不想去测试,保守点取1即,Nthreads=Ncpu*(1+1)=2Ncpu。这样设置一般都OK。
CPU密集型: 假设没有等待w=0,则W/C=0. Nthreads=Ncpu。
再次归纳下:
IO密集型 = 2Ncpu(可以测试后自己控制大小,2Ncpu一般没问题)(常出现于线程中:数据库数据交互、文件上传下载、网络数据传输等等)
CPU密集型 = Ncpu(常出现于线程中:复杂算法)
java中:Ncpu = Runtime.getRuntime().availableProcessors()
4,继续研究
A派的另一个说法
即对于计算密集型的任务,在拥有N个处理器的系统上,当线程池的大小为N+1时,通常能实现最优的效率。(即使当计算密集型的线程偶尔由于缺失故障或者其他原因而暂停时,这个额外的线程也能确保CPU的时钟周期不会被浪费。)
即,计算密集型=Ncpu+1,但是这种做法导致的多一个cpu上下文切换是否值得,这里不考虑。读者可自己考量。
本文借鉴归纳:Flag Counter 《根据CPU核心数确定线程池并发线程数》
深入理解-CPU核心数与线程池并发线程数关系相关推荐
- 由浅入深理解Java线程池及线程池的如何使用
前言 多线程的异步执行方式,虽然能够最大限度发挥多核计算机的计算能力,但是如果不加控制,反而会对系统造成负担.线程本身也要占用内存空间,大量的线程会占用内存资源并且可能会导致Out of Memory ...
- 【Java 并发编程】线程池机制 ( 线程池执行任务细节分析 | 线程池执行 execute 源码分析 | 先创建核心线程 | 再放入阻塞队列 | 最后创建非核心线程 )
文章目录 一.线程池执行任务细节分析 二.线程池执行 execute 源码分析 一.线程池执行任务细节分析 线程池执行细节分析 : 核心线程数 101010 , 最大小成熟 202020 , 非核心线 ...
- java线程池1001java线程池_深入浅出Java(Android )线程池ThreadPoolExecutor
前言 关于线程池 在Java/Android开发中,设计到并发的请求,那基本上是离不开线程池了.用线程池的好处: 1.减少线程频繁创建.销毁的开销: 2.好控制并发量,降低OOM的可能,至于原因文中会 ...
- DirectX12(D3D12)基础教程(十六)——实现渲染线程池:3个内核同步对象实现渲染线程池/大规模线程池
文章目录 1.前言 2.深入了解MsgWaitForMultipleObjects()函数fWaitAll参数为TRUE时的问题 3.内核同步对象:CPU线程屏障(CPU Barrier)基础知识 4 ...
- 【Android 异步操作】线程池 ( 线程池简介 | 线程池初始化方法 | 线程池种类 | AsyncTask 使用线程池示例 )
文章目录 一.线程池简介 二.线程池初始化方法简介 三.线程池使用示例 一.线程池简介 线程池一般是实现了 ExecutorService 接口的类 , 一般使用 ThreadPoolExecutor ...
- 【转】1.2异步编程:使用线程池管理线程
从此图中我们会发现 .NET 与C# 的每个版本发布都是有一个"主题".即:C#1.0托管代码→C#2.0泛型→C#3.0LINQ→C#4.0动态语言→C#5.0异步编程.现在我为 ...
- 线程池最佳线程数量到底要如何配置?
一.前言 对于从事后端开发的同学来说,线程是必须要使用了,因为使用它可以提升系统的性能.但是,创建线程和销毁线程都是比较耗时的操作,频繁的创建和销毁线程会浪费很多CPU的资源. 此外,如果每个任务都创 ...
- mysql 关闭线程池_线程池安全的关闭方式
对于一些定时任务或者网络请求服务将会使用线程池,当应用停机时需要正确安全的关闭线程池,如果处理不当,可能造成数据丢失,业务请求结果不正确等问题. 关闭线程池我们可以选择什么都不做,JVM 关闭时自然的 ...
- threadpoolexecutor创建线程池_线程池ThreadPoolExecutor源码分析
什么是线程池 创建线程要花费昂贵的资源和时间,如果任务来了才创建那么响应时间会变长,而且一个进程能创建的线程数量有限.为了避免这些问题,在程序启动的时候就创建若干线程来响应出来,它们被称为线程池,里面 ...
最新文章
- MySQL查询优化:LIMIT 1避免全表扫描
- 田志刚:人跟人差距怎么那么大呢?
- linux怎么远程windows桌面,Windows系统怎么远程登陆桌面Linux?
- ASP中 Request.Form中文乱码的解决方法
- P2408 不同子串个数
- 计算2的N次方(信息学奥赛一本通-T1170)
- 【云周刊】第145期:2017天猫双11总交易额1682亿,背后阿里绝密50+技术揭秘!
- python webqq机器人_[代码全屏查看]-python3.2模拟登录webqq
- 新手如何搭建淘宝客网站,实用教程
- Sketch for Mac(矢量绘图工具)
- 基于51单片机DTH11温湿度测量仪protues仿真设计_LCD显示
- 司普沃浅谈蓝莓种植技术与管理
- Python爬虫(4)-Selenium模拟鼠标操作
- 关于微信小程序Tomcat服务器后端程序搭建
- 21.后台运行frp服务
- 圆周率近似计算matlab,matlab 圆周率的近似计算 实验报告.doc
- 几何画板 linux,用几何画板怎么作函数图像
- 去除Flexgrid表格的隔行底色为白的样式
- C# 窗体 TreeView控件
- 创新创造蓝海 远程接入行业又添新品
热门文章
- 6.3 快速更改图表的数据源 [原创Excel教程]
- 数字图像处理之颜色空间
- 盘点团队在线帮助文档怎么做?
- 概率论之 几个难的分布题型汇总(泊松,指数,正态)
- luogu[U103720]薇尔莉特 题解
- 分享:作为程序员,为什么你应该学好数学?
- 关于“微信订阅号/制作相册”
- 金蝶EAS,扩展报表,Java数据集代码示例
- Separation Studio for Mac(分色工具)
- 【Python Brain】SNN脉冲神经网络开源模拟器 The Brian Simulator 仿真指南