在高并发的情况下采用线程池,有效的降低了线程创建释放的时间花销及资源开销,如不使用线程池,有可能造成系统创建大量线程而导致消耗完系统内存以及”过度切换”。(在JVM中采用的处理机制为时间片轮转,减少了线程间的相互切换)
那么在高并发的情况下,我们怎么选择最优的线程数量呢?选择原则又是什么呢?这个问题去哪网的技术总监问过我,这里总结一下。
第一种:
了解更多,请关注 公众号 “ code 杂坛 “!
如果是CPU密集型应用,则线程池大小设置为N+1;(对于计算密集型的任务,在拥有N个处理器的系统上,当线程池的大小为N+1时,通常能实现最优的效率。(即使当计算密集型的线程偶尔由于缺失故障或者其他原因而暂停时,这个额外的线程也能确保CPU的时钟周期不会被浪费。摘自《Java Concurrency In Practise》)

如果是IO密集型应用,则线程池大小设置为2N+1

任务一般可分为:CPU密集型、IO密集型、混合型,对于不同类型的任务需要分配不同大小的线程池。CPU密集型任务 尽量使用较小的线程池,一般为CPU核心数+1。 因为CPU密集型任务使得CPU使用率很高,若开过多的线程数,只能增加上下文切换的次数,因此会带来额外的开销。IO密集型任务 可以使用稍大的线程池,一般为2*CPU核心数。 IO密集型任务CPU使用率并不高,因此可以让CPU在等待IO的时候去处理别的任务,充分利用CPU时间。混合型任务 可以将任务分成IO密集型和CPU密集型任务,然后分别用不同的线程池去处理。 只要分完之后两个任务的执行时间相差不大,那么就会比串行执行来的高效。 因为如果划分之后两个任务执行时间相差甚远,那么先执行完的任务就要等后执行完的任务,最终的时间仍然取决于后执行完的任务,而且还要加上任务拆分与合并的开销,得不偿失。

第二种呢,先由之前遇到的一个测试题说起,假设要求一个系统的TPS(Transaction Per Second或者Task Per Second)至少为20,然后假设每个Transaction由一个线程完成,继续假设平均每个线程处理一个Transaction的时间为4s。那么问题转化为:

如何设计线程池大小,使得可以在1s内处理完20个Transaction?
了解更多,请关注 公众号 “ code 杂坛 “!
计算过程很简单,每个线程的处理能力为0.25TPS,那么要达到20TPS,显然需要20/0.25=80个线程。
这个理论上成立的,但是实际情况中,一个系统最快的部分是CPU,所以决定一个系统吞吐量上限的是CPU。增强CPU处理能力,可以提高系统吞吐量上限。在考虑时需要把CPU吞吐量加进去。在IO优化文档中,有这样地公式:
最佳线程数目 = ((线程等待时间+线程CPU时间)/线程CPU时间 )* CPU数目
即线程等待时间所占比例越高,需要越多线程。线程CPU时间所占比例越高,需要越少线程。
但根据短板效应,真实的系统吞吐量并不能单纯根据CPU来计算。那要提高系统吞吐量,就需要从“系统短板”(比如网络延迟、IO)着手:

尽量提高短板操作的并行化比率,比如多线程下载技术
增强短板能力,比如用NIO替代IO尽量提高短板操作的并行化比率,比如多线程下载技术
增强短板能力,比如用NIO替代IO

第一条可以联系到Amdahl定律,这条定律定义了串行系统并行化后的加速比计算公式:

加速比=优化前系统耗时 / 优化后系统耗时

加速比越大,表明系统并行化的优化效果越好。Addahl定律还给出了系统并行度、CPU数目和加速比的关系,加速比为Speedup,系统串行化比率(指串行执行代码所占比率)为F,CPU数目为N:

Speedup <= 1 / (F + (1-F)/N)

当N足够大时,串行化比率F越小,加速比Speedup越大。
了解更多,请关注 公众号 “ code 杂坛 “!

这时候又抛出是否线程池一定比但线程高效的问题?

答案是否定的,比如Redis就是单线程的,但它却非常高效,基本操作都能达到十万量级/s。从线程这个角度来看,部分原因在于:

多线程带来线程上下文切换开销,单线程就没有这种开销
锁

当然“Redis很快”更本质的原因在于:
Redis基本都是内存操作,这种情况下单线程可以很高效地利用CPU。而多线程适用场景一般是:存在相当比例的IO和网络操作。

总的来说,应用情况不同,采取多线程/单线程策略不同;线程池情况下,不同的估算,目的和出发点是一致的。

参考借鉴:http://ifeve.com/how-to-calculate-threadpool-size/
https://www.zhihu.com/question/38128980
相互学习,共同进步!

了解更多,请关注 公众号 “ code 杂坛 “!

并发下线程池的数量计算相关推荐

  1. Executors线程池关闭时间计算

    Executors线程池关闭时间计算 学习了:http://blog.csdn.net/wo541075754/article/details/51564359 https://www.cnblogs ...

  2. 自定义线程池拒绝策略缓解高并发下线程池压力

    一. 默认的拒绝策略 ThreadPoolExceutor.AbortPolicy : 丢弃任务并抛出RejectedExecutionException异常.         ThreadPoolE ...

  3. 并发下线程池的最佳数量计算

    原文地址:https://blog.csdn.net/qq_34417408/article/details/78895573

  4. threadpool的数量_多线程之旅(11)_如何限制系统线程池ThreadPool的最大最小并发数量_SetMaxThreads/SetMinThreads用法...

    ThreadPool有两个设置线程池并发数量的方法,分别是: ThreadPool.SetMinThreads(int workerThreads, int completionPortThreads ...

  5. 创建线程那么容易,为什么非要让我使用线程池?(深深深入剖析)

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 一.概述 1.问题 先看我们遇到的问题:我们创建线程的方式很简单, ...

  6. 由于不知线程池的bug,某Java程序员叕被祭天

    说说你对线程池的理解? 首先明确,池化的意义在于缓存,创建性能开销较大的对象,比如线程池.连接池.内存池.预先在池里创建一些对象,使用时直接取,用完就归还复用,使用策略调整池中缓存对象的数量. Jav ...

  7. 线程及同步的性能 – 线程池/ ThreadPoolExecutors/ ForkJoinPool

    线程池和ThreadPoolExecutors 虽然在程序中可以直接使用Thread类型来进行线程操作,但是更多的情况是使用线程池,尤其是在Java EE应用服务器中,一般会使用若干个线程池来处理来自 ...

  8. Java线程池 源码分析

    1.个人总结及想法: (1)ThreadPoolExecutor的继承关系? ThreadPoolExecutor继承AbstractExectorService,AbstractExecutorSe ...

  9. Android线程池封装库

    目录介绍 1.遇到的问题和需求 1.1 遇到的问题有哪些 1.2 遇到的需求 1.3 多线程通过实现Runnable弊端 1.4 为什么要用线程池 2.封装库具有的功能 2.1 常用的功能 3.封装库 ...

最新文章

  1. 16-acrobat por 简单使用指南
  2. 动态规划算法解最长公共子序列LCS问题
  3. mysql数据库优化大全_MySQL数据库优化技巧大全
  4. Go语言 模糊搜索实验(一)
  5. tensorflow log 日志级别设置
  6. 快手高级Java四轮面试题:设计模式+红黑树+Java锁+Redis等
  7. JavaScript大杂烩4 - 理解JavaScript对象的继承机制
  8. python 列表副本_列表副本不工作?
  9. express中间件系统的基本实现
  10. JAVA利用JXL导出/生成 EXCEL1
  11. 【NOIP2007】【Luogu1093】奖学金
  12. 如何在Mac上删除其他存储
  13. 图片转文字软件哪个好?推荐这几款良心软件
  14. 从小锁匠铺到工业造纸巨头,这家德国百年家族企业不断改写世界工程技术史 | 能动观察...
  15. 参考文献引用详细教程
  16. SQL 计算月同比、月环比
  17. 友善之臂最新版mini2440学习笔记——u-boot 1.1.6移植(一)
  18. word 2016 无法输入中文 输入法失效 只能输入英文
  19. PAKDD 2019 AutoML 挑战赛圆满落幕,中国队伍包揽前三...
  20. wemos学习之串口通信和ESP8266wifi模块的调用

热门文章

  1. sed基本用法介绍1
  2. java 在linux创建文件或目录 设置权限
  3. 前端vscode编辑器中文文件夹乱码的情况
  4. Oculus Quest 2 和 Unity 的 VR 开发基础知识
  5. 解读手机拍照的各个参数(文档模式)
  6. Android11 热点设置永不关闭
  7. soa理念_我们的理念很简单
  8. 计算机安装操作系统后 操作系统即驻留在,江苏省计算机等级考试一级历年真题(06-12)第三章计算机软件附答案...
  9. 域名注册 API 已全面支持
  10. 华为mate30连接电脑linux,对飚iPad Pro的华为MatePad此新功能或许你没想到