快速业务通道

使用Java构建高伸缩性组件 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-17
ent包的无锁的 FIFO(先进先出)队列。该队列采用的算法基于单链表的并发操作,最初由 Michael和 Scott开发。它的出列操作需要一次比较—交换,而入列操作需要两次比较—交换。这对 入列和出列操作来说太容易了。但是分析数据(图 2)显示比较—交换操作占用了大部分 执行时间,同时入列操作需要两次交换—比较,这增加了失败的概率。在现代多处理器上 ,一次成功的比较—交换操作要比一次加载或者存储的时间长一个数量级,因为它们需要 独立占用和冲刷处理器写缓存。

图2. CAS操作的执行时间

从图2可以看出,CAS操作执行时间的百分比为46.08%,几乎占了全部执行时间的一半 。分析数据有一个操作的延迟。真正的时间是在"SETE AL"指令之后发生的。

Mozes和Shavit(MoS-queue)在它们的无锁队列算法中,提供了一种新颖的办法来降 低入列操作时CAS的数量。其关键点在于替换单链表,因为其中的指针在插入时需要浪费 一次CAS操作,取而代之的是采用一个双链表,其中的指针在更新时只需要一次存储操作 ,如果事件乱序导致双链表不一致则可以修复。

我们做了一次基准测试来比较ConcurrentLinkedQueue(JSR166y)和Mos-Queue的性能 。结果在图3中显示。对于大量线程来说,Mos-Queue的性能优于JDK ConcurrentLinkedQueue。

图3. 性能比较:ConcurrentLinkedQueue和Mos-Queue

更多有关Mos-Queue的信息参见Mozes和Shavit的论文《An Optimistic Approach to Lock-Free FIFO Queues》。

使用Java构建高伸缩性组件(4)

时间:2011-03-29 infoq 译:崔康

减少内存分配

Java虚拟机拥有一套强大、有效的内存管理体系。垃圾回收器能够压缩现有对象,以 确保在垃圾回收之后Java堆里没有空隙。因为空闲空间在垃圾回收之后都是连续的,所以 内存分配不多是增加了一个指针而已。

这对多线程应用同样有效,如果内存使用不敏感的话。JVM为每一个线程分配了一个线 程范围的缓存。在内存分配时,线程范围的缓存首先被使用。只有在线程范围的缓存被耗 尽之后才会使用全局堆。

在线程范围内分配内存对应用性能非常有益,但是如果分配过于频繁,则会不起作用 。根据我们的经验,线程范围的缓存在分配频率高的情况下会很快耗尽。

如果在循环中需要暂时性的对象,则线程范围的类会比较有益。如果我们在线程本地 对象中存储临时对象,我们可以在每一次循环迭代中重用它。虽然,线程本地类会增加额 外的负担,但是大多数时候都比在内存中频繁分配内存要好。

图 4.性能比较:线程本地和分配

结论

在本文中,我们介绍了使用Java创建高扩展性组件的几个重要原则。一般来说,这些 原则通常很有帮助,但是它们无法替代谨慎的测试和性能调优。

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号