别再纠结线程池大小 + 线程数量了,没有固定公式的!.docx

别再纠结线程池大小 + 线程数量了,没有固定公式的!.docx

  1. 1、本文档共12页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
别再纠结线程池大小 + 线程数量了,没有固定公式的! 2021-05-21 可能很多人都看到过一个线程数设置的理论: CPU 密集型的程序 - 核心数 + 1 I/O 密集型的程序 - 核心数 * 2 不会吧,不会吧,真的有人依据这个理论规划线程数? 线程数和CPU利用率的小测试 抛开一些操作系统,计算机原理不谈,说一个基本的理论(不用纠结能否严谨,只为好理解):一个CPU核心,单位时间内只能执行一个线程的指令?** 那么理论上,我一个线程只需要不停的执行指令,就可以跑满一个核心的利用率。 来写个死循环空跑的例子验证一下: 测试环境:AMD Ryzen 5 3600, 6 - Core, 12 - Threads public?class?CPUUtilizationTest?{ ????public?static?void?main(String[]?args)?{ ????????//死循环,什么都不做 ????????while?(true){ ????????} ????} } 运转这个例子后,来看看现在CPU的利用率: 从图上可以看到,我的3号核心利用率已经被跑满了 那基于上面的理论,我多开几个线程试试呢? public?class?CPUUtilizationTest?{ ?public?static?void?main(String[]?args)?{ ??for?(int?j?=?0;?j?<?6;?j++)?{ ???new?Thread(new?Runnable()?{ ????@Override ????public?void?run()?{ ?????while?(true){ ?????} ????} ???}).start(); ??} ?} } 此时再看CPU利用率,1/2/5/7/9/11 几个核心的利用率已经被跑满: 那假如开12个线程呢,是不是会把全部核心的利用率都跑满?答案肯定是会的: 假如此时我把上面例子的线程数连续添加到24个线程,会消灭什么结果呢? 从上图可以看到,CPU利用率和上一步一样,还是全部核心100%,不过此时负载已经从11.x添加到了22.x(load average解释参考/blog/unders…),说明此时CPU更繁忙,线程的任务无法准时执行。 现代CPU基本都是多核心的,比如我这里测试用的AMD 3600,6核心12线程(超线程),我们可以简约的认为它就是12核心CPU。那么我这个CPU就可以同时做12件事,互不打搅。 假如要执行的线程大于核心数,那么就需要通过操作系统的调度了。操作系统给每个线程安排CPU时间片资源,然后不停的切换,从而实现“并行”执行的效果。 但是这样真的更快吗?从上面的例子可以看出,一个线程?就可以把一个核心?的利用率跑满。假如每个线程都很“霸道”,不停的执行指令,不给CPU空闲的时间,并且同时执行的线程数大于CPU的核心数,就会导致操作系统更频繁的执行切换线程执行?,以确保每个线程都可以得到执行。 不过切换是有代价的,每次切换会伴随着寄存器数据更新,内存页表更新等操作?。虽然一次切换的代价和I/O操作比起来微不足道,但假如线程过多,线程切换的过于频繁,甚至在单位时间内切换的耗时已经大于程序执行的时间,就会导致CPU资源过多的铺张在上下文切换上,而不是在执行程序,得不偿失。 上面死循环空跑的例子,有点过于极端了,正常情况下不太可能有这种程序。 大多程序在运转时都会有一些 I/O操作,可能是读写文件,网络收发报文等,这些 I/O 操作在进行时时需要等待反馈的。比如网络读写时,需要等待报文发送或者接收到,在这个等待过程中,线程是等待形态,CPU没有工作。此时操作系统就会调度CPU去执行其他线程的指令,这样就完善利用了CPU这段空闲期,提高了CPU的利用率。 上面的例子中,程序不停的循环什么都不做,CPU要不停的执行指令,几乎没有啥空闲的时间。假如插入一段I/O操作呢,I/O 操作期间 CPU是空闲形态,CPU的利用率会怎样样呢?先看看单线程下的结果: public?class?CPUUtilizationTest?{ ?public?static?void?main(String[]?args)?throws?InterruptedException?{ ??for?(int?n?=?0;?n?<?1;?n++)?{ ???new?Thread(new?Runnable()?{ ????@Override ????public?void?run()?{ ?????while?(true){ ????????????????????????//每次空循环?1亿?次后,sleep?50ms,模仿?I/O等待、切换 ??????for

文档评论(0)

bob157641554 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档