Java 6中的线程优化真的有效么? - 编程入门网
个锁上的自旋时间以及锁的拥有者的状态。如果在 同一个锁对象上,自旋刚刚成功过,并且持有锁的线程正在运行中,那么自旋很 有可能再次成功。进而它将被应用于相对更长的时间,比如100个循环。另一方面 ,如果自旋很少发生过,它将被遗弃,避免浪费任何CPU周期。
StringBuffer vs. StringBuilder的基准测试 但是要想设计出一种方法来判断这些巧妙的优化方法到底多有效,这条路并不 平坦。首要的问题就是如何设计基准测试。为了找到问题的答案,我决定去看看 人们通常在代码中运用了哪些常见的技巧。我首先想到的是一个非常古老的问题 :使用StringBuffer代替String可以减少多少开销? 一个类似的建议是,如果你希望字符串是可变的,就应该使用StringBuffer。 这个建议的缘由是非常明确的。String是不可变的,但如果我们的工作需要字符 串有很多变化,StringBuffer将是一个开销较低的选择。有趣的是,在遇到JDK 1.5中的StringBuilder(它是StringBuffer的非同步版本)后,这条建议就不灵 了。由于StringBuilder与 StringBuffer之间唯一的不同在于同步性,这似乎说 明,测量两者之间性能差异的基准测试必须关注在同步的开销上。我们的探索从 第一个问题开始,非竞争锁的开销如何? 这个基准测试的关键(如清单1所示)在于将大量的字符串拼接在一起。底层 缓冲的初始容量足够大,可以包含三个待连接的字符串。这样我们可以将临界区 内的工作最小化,进而重点测量同步的开销。 Java 6中的线程优化真的有效么?(3)时间:2011-05-20 infoq.com Jeroen Borgers 译:韩锴基准测试的结果 下图是测试结果,包括EliminateLocks、UseBiasedLocking和 DoEscapeAnalysis的不同组合。 图3. 基准测试的结果 关于结果的讨论 之所以使用非同步的StringBuilder,是为了提供一个测量性能的基线。我也 想了解一下各种优化是否真的能够影响StringBuilder的性能。正如我们所看到的 ,StringBuilder的性能可以保持在一个不变的吞吐量水平上。因为这些技术的目 标在于锁的优化,因此这个结果符合预期。在性能测试的另一栏中我们也可以看 到,使用没有任何优化的同步的StringBuffer,其运行效率比StringBuilder大概 要慢三倍。 仔细观察图3的结果,我们可以注意到从左到右性能有一定的提高,这 可以归功于EliminateLocks。不过,这些性能的提升比起偏向锁来说又显得有些 苍白。事实上,除了C列以外,每次运行时如果开启偏向锁最终都会提供大致相同 的性能提升。但是,C列是怎么回事呢? 在处理最初的数据的过程中,我注意到有一项测试在六个测试中要花费 格外长的时间。由于结果的异常相当明显,因此基准测试似乎在报告两个完全不 同的优化行为。经过一番考虑,我决定同时展示出高值和低值(B列和C列)。由 于没有更深入的研究,我只能猜测这里应用了一种以上的优化(很可能是两种) ,并且存在一些竞争条件,偏向锁大多时候会取胜,但不非总能取胜。如果另一 种优化占优了,那么偏向锁的效果要么被抑制,要么就被延迟了。 这种奇怪的现象是逸出分析导致的。明确了这个基准测试的单线程化的本质后 ,我期待着逸出分析会消除锁,从而将StringBuffer的性能提到了与 StringBuilder相同的水平。但是很明显,这并没有发生。还有另外一个问题;在 我的机器上,每一次运行的时间片分配都不尽相同。更为复杂的是,我的几位同 事在他们的机器上运行这些测试,得到的结果更混乱了。在有些时候,这些优化 并没有将程序提速那么多。 前期的结论 尽管图3列出的结果比我所期望的要少,但确实可以从中看出各种优化能够除 去锁产生的大部分开销。但是,我的同事在运行这些测试时产生了不同的结果, 这似乎对测试结果的真实性提出了挑战。这个基准测试真的测 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |