使用Java构建高伸缩性组件
2009-12-21 00:00:00 来源:WEB开发网举例来说,如果应用有100个线程,并且所有的线程都需要从一个java.util.HashTable提取/存储元素,该应用的性能由于线程竞争会下降。每一个线程需要在访问该HashTable之前等待很长时间。
如果我们使用类似JLM的工具就会发现,该Hash表关联的monitor使用非常频繁。解决这一问题的办法是使用能够替代HashTable的高扩展性 组件。在本例中,我们可以通过java.util.concurrent.ConcurrentHashMap替换该hash表。 ConcurrentHashMap把它的内部数据结构分成若干段。在应用中使用ConcurrentHashMap替换HashMap替换使线程针对多个子组件竞争而不是单个大组件。使用ConcurrentHashMap的应用产生竞争的几率比之前要小得多。
还有一种办法降低访问共享组件的竞争几率。如果一个组件具有相反语义的操作,如栈的压入和弹出,这两种操作可以无需接触核心数据结构即可完成。这种技术最 早由Danny Hendler、Nir Shavit和Lena Yerushalmi引入,已经在Amino库中实现。这种方法的性能改善见图1。
图1.性能比较:EBStack和TreiberStack
使用无锁/无等待算法
传统上,大家都采用基于锁的方法来确保共享数据的一致性和对关键区域的互斥访问。锁的概念易懂,但基于锁的算法引起了很多挑战。其中一些著名的问题包括死锁、活锁、优先级倒置和锁竞争等。锁竞争会减少组件和算法的可扩展性。
无锁和无等待算法到现在已经存在二十多年了。它们被认为可以能够解决大部分与锁有关的问题。这些算法支持在不使用任何锁算法的情况下更新共享数据结构,不仅如此,还有助于创建扩展性良好的算法。最初,这些无锁和无等待的算法纯粹是理论兴趣。但是,随着算法社区的发展和新硬件的支持,无锁技术在现实产品中得到了越来越多的应用,比如操作系统内核、虚拟机、线程库等。
更多精彩
赞助商链接