
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
可扩展性是程序员在开发软件应用的时候需要满足的一个编程需求,而本我们就通过案例分析来简单了解一下,Java编程可扩展性需要注意哪些问题。
不要给内存系统太大的压力
如果线程执行过程中需要分配内存,这在Java中通常不会造成问题。现代的JVM是高度优化的,它通常为每个线程保留一块Buffer,这样在分配内存时,只要buffer没有用光,那么就不需要和全局的堆打交道。而本地buffer分配完毕之后,JVM将不得不到全局堆中分配内存,这样通常会带来严重的可扩展性的降低。另外,给GC带来的压力也会进一步降低程序的可扩展性。尽管我们有并行的GC,但其可扩展性通常并不理想。如果一个循环执行的程序在每次执行中都需要分配临时对象,那么我们可以考虑利用ThreadLocal和SoftReference这样的技术来减少内存的分配。
使用ThreadLocal
ThreadLocal类能够被用来保存线程私有的状态信息,对于某些应用非常方便。通常来讲,它对可扩展性有正面的影响。它能为各个线程提供一个线程私有的变量,因而多个线程之间无须同步。需要注意的是在JDK1.6之前,ThreadLocal有着相当低效的实现,如果需要在JDK1.5或更老的版本上使用ThreadLocal,需要慎重评估其对性能的影响。类似的,目前JDK6中的ReentrantReadWriteLock的实现也相当低效,如果想利用读锁之间不互斥的特性来提高可扩展性,同样需要进行profile来确认其适用程度。
锁的粒度很重要
粗粒度的全局锁在保证线程安全的同时,也会损害应用的性能。仔细考虑锁的粒度在构建高可扩展Java应用时非常重要。当CPU个数和线程数较少时,全局锁并不会引起激烈的竞争,因此获得一个锁的代价很小(JVM对这种情况进行了优化)。随着CPU个数和线程数增多,对全局锁的竞争越来越激烈。除了一个获得锁的CPU可以继续工作外,其他试图获得该锁的CPU都只能闲置等待,导致整个系统的CPU利用率过低,系统性能不能得到充分利用。当我们遇到一个竞争激烈的全局锁时,可以尝试将锁划分为多个细粒度锁,每一个细粒度锁保护一部分共享资源。通过减小锁的粒度,可以降低该锁的竞争程度。
通过使用细粒度锁,提高HashMap在多线程应用中的性能。在ConcurrentHashMap中,默认构造函数使用16个锁保护整个HashMap。用户可以通过参数设定使用上千个锁,这样相当于将整个HashMap划分为上千个碎片,每个碎片使用一个锁进行保护。
【免责声明】本文系本网编辑部分转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与管理员联系,我们会予以更改或删除相关文章,以保证您的权益!更多内容请加danei0707学习了解。欢迎关注“达内在线”参与分销,赚更多好礼。