Java 线程池 -03

怎么合理的设置线程池大小呢

感谢:http://ifeve.com/how-to-calculate-threadpool-size/

Java中任务分为CPU密集型和IO密集型
第一种:

  • 如果是CPU密集型应用,则线程池大小设置为N+1
  • 如果是IO密集型应用,则线程池大小设置为2N+1
    如果一台服务器上只部署这一个应用并且只有这一个线程池,那么这种估算或许合理,具体还需自行测试验证。

第二种:
公式:最佳线程数目 = ((线程等待时间+线程CPU时间)/线程CPU时间 )* CPU数目
=(线程等待时间/线程CPU时间+1)CPU数目
=线程等待时间/线程CPU时间
CPU数目 + 1*CPU数目

可以看出 如果CPU数量固定的情况下,线程等待时间越长所需线程越多越好 这也跟第一种方法相呼应

比如每个任务消耗CPU时间为0.2秒 CPU等待时间为0.6秒 CPU数为16
那么需要的线程数为:0.2/0.6*16+16 = 1.92+6 ≈18个

一个系统最快的部分是CPU ,所以决定一个系统吞吐量上限的是CPU .增强CPU处理能力(不让CPU闲着 它又不怕累),可以有效提高系统吞吐量,但是CPU也不是唯一决定吞吐量的因素,网络与IO等也有很大关系。

  • 多种因素决定的吞吐量 就类似木桶短板一样 最低的那块版会影响整体性能 所以我们要尽量提高短板操作的并行化效率,比如多线程下载(每个下载都占用IO 我可以让多个线程处理 )要是文件比较大的话 用单线程下载 那用户就疯了!
  • 增强短板能力,比如IO流用NIO 不阻塞 跟AJAX的异步请求一样 让人体验很好

加速比
Addahl定律提出的 加速比=优化前系统耗时/优化后系统耗时
比如上边说的多线程下载文件,比如一个10G的文件 单线程需要10分钟 5个线程下载需要14分钟 那么 加速比=10/15 = 0.67
加速比越大说明优化越明显,优化效果越好。

Addahl定律提出的另一个公式: Speedup <= 1 / (F + (1-F)/N)
加速比<=1/(系统串行化比例+(1-系统串行化比例)/CPU数)
系统串行化比例就是串行执行代码比例
这个公式看出 当N足够大时 串行化比率F越小,加速比Speedup越大。

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

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

所以即使有上面的简单估算方法,也许看似合理,但实际上也未必合理,都需要结合系统真实情况(比如是IO密集型或者是CPU密集型或者是纯内存操作)和硬件环境(CPU、内存、硬盘读写速度、网络状况等)来不断尝试达到一个符合实际的合理估算值。

说实话 不是很懂 懂得也就知道有CPU密集型和IO密集型 不管什么情况 都需要根据实际情况来说

发布了431 篇原创文章 · 获赞 91 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/qq_36291682/article/details/89929317