Java并发编程:性能、扩展性和响应精读.docxVIP

Java并发编程:性能、扩展性和响应精读.docx

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
1、介绍本文讨论的重点在于多线程应用程序的性能问题。我们会先给性能和扩展性下一个定义,然后再仔细学习一下Amdahl法则。下面的内容我们会考察一下如何用不同的技术方法来减少锁竞争,以及如何用代码来实现。2、性能我们都知道,多线程可以用来提高程序的性能,背后的原因在于我们有多核的CPU或多个CPU。每个CPU的内核都可以自己完成任务,因此把一个大的任务分解成一系列的可彼此独立运行的小任务就可以提高程序的整体性能了。可以举个例子,比如有个程序用来将硬盘上某个文件夹下的所有图片的尺寸进行修改,应用多线程技术就可以提高它的性能。使用单线程的方式只能依次遍历所有图片文件并且执行修改,如果我们的CPU有多个核心的话,毫无疑问,它只能利用其中的一个核。使用多线程的方式的话,我们可以让一个生产者线程扫描文件系统把每个图片都添加到一个队列中,然后用多个工作线程来执行这些任务。如果我们的工作线程的数量和CPU总的核心数一样的话,我们就能保证每个CPU核心都有活可干,直到任务被全部执行完成。对于另外一种需要较多IO等待的程序来说,利用多线程技术也能提高整体性能。假设我们要写这样一个程序,需要抓取某个网站的所有HTML文件,并且将它们存储到本地磁盘上。程序可以从某一个网页开始,然后解析这个网页中所有指向本网站的链接,然后依次抓取这些链接,这样周而复始。因为从我们对远程网站发起请求到接收到所有的网页数据需要等待一段时间,所以我们可以将此任务交给多个线程来执行。让一个或稍微更多一点的线程来解析已经收到的HTML网页以及将找到的链接放入队列中,让其他所有的线程负责请求获取页面。与上一个例子不同的是,在这个例子中,你即便使用多于CPU核心数量的线程也仍然能够获得性能提升。上面这两个例子告诉我们,高性能就是在短的时间窗口内做尽量多的事情。这个当然是对性能一词的最经典解释了。但是同时,使用线程也能很好地提升我们程序的响应速度。想象我们有这样一个图形界面的应用程序,上方有一个输入框,输入框下面有一个名字叫“处理”的按钮。当用户按下这个按钮的时候,应用程序需要重新对按钮的状态进行渲染(按钮看起来被按下了,当松开鼠标左键时又恢复原状),并且开始对用户的输入进行处理。如果处理用户输入的这个任务比较耗时的话,单线程的程序就无法继续响应用户其他的输入动作了,比如,来自操作系统传送过来的用户单击鼠标事件或鼠标指针移动事件等等,这些事件的响应需要有独立的线程来响应。可扩展性(Scalability)的意思是程序具备这样的能力:通过添加计算资源就可以获得更高的性能。想象我们需要调整很多图片的大小,因为我们机器的CPU核心数是有限的,所以增加线程数量并不总能相应提高性能。相反,因为调度器需要负责更多线程的创建和关闭,也会占用CPU资源,反而有可能降低性能。2.1?Amdahl法则上一段提到了在某些情形下,添加额外的运算资源可以提高程序的整体性能。为了能够计算出当我们添加了额外的资源的时候到底能获得多少性能提升,我们有必要来检查一下程序有哪些部分是串行运行(或同步运行),有哪些部分是并行运行的。如果我们把需要同步执行的代码占比量化为B(例如,需要同步执行的代码的行数),把CPU的总核心数记为n,那么,根据Amdahl法则,我们可以获得的性能提升的上限是:如果n趋于无穷大的话,(1-B)/n就收敛于0。因此,我们可以忽略这个表达式的值,因此性能提升位数收敛于1/B,这里面的B代表是那些必须同步运行的代码比例。如果B等于0.5的话,那意味着程序的一半代码无法并行运行,0.5的倒数是2,因此,即使我们添加无数个CPU核心,我们获得的性能提升也最多是2倍。假设我们现在把程序修改了一下,修改之后只有0.25的代码必须同步运行,现在1/0.25=4,表示我们的程序如果在具有大量CPU的硬件上运行时速度将会比在单核的硬件上快大概4倍。另一方面,通过Amdahl法则,我们也能根据我们想获得的提速的目标计算出程序应该的同步代码的比例。如果我们想要达到100倍的提速,而1/100=0.01,意味着,我们程序同步执行的代码的数量最多不能超过1%。总结Amdahl法则我们可以看出,我们通过添加额外CPU来获得性能提升的最大值取决于程序同步执行部分代码所占的比例有多小。虽然在实际中,想要计算出这个比例并不总是那么容易,更别说面对一些大型的商业系统应用了,但是Amdahl法则给了我们很重要的启示,那就是,我们必须非常仔细地去考虑那些必须同步执行的代码,并且力图减少这部分代码。2.2?对性能的影响文章写到这里,我们已经表明这样一个观点:增加更多的线程可以提高程序的性能和响应速度。但是另一方面,想要取得这些好处却并非轻而易举,也需要付出一些代价。线程的使用对性能的提升也会有所影响。首先,第一个影响来自线程创建的时候

文档评论(0)

1112111 + 关注
实名认证
文档贡献者

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

1亿VIP精品文档

相关文档