如何提高Java并行程序性能

 我来答
电商运营的机会
2017-06-10 · 知道合伙人互联网行家
电商运营的机会
知道合伙人互联网行家
采纳数:436 获赞数:998
潭州教育网络科技有限公司最佳电商运营总监。

向TA提问 私信TA
展开全部

在Java程序中,多线程几乎已经无处不在。与单线程相比,多线程程序的设计和实现略微困难,但通过多线程,却可以获得多核CPU带来的性能飞跃,从这个角度说,多线程是一种值得尝试的技术。

1.有关多线程的误区:线程越多,性能越好

不少初学者可能认为,线程数量越多,那么性能应该越好。因为程序给的直观感受总是这样。一个两个线程可能跑的很难,线程一多可能就快了。但事实并非如此。因为一个物理CPU一次只能执行一个线程,多个线程则意味着必须进行线程的上下文切换,而这个代价是很高的。因此,线程数量必须适量,最好的情况应该是N个CPU使用N个线程,并且让每个CPU的占有率都达到100%,这种情况下,系统的吞吐量才发挥到极致。但现实中,不太可能让单线程独占CPU达到100%,一个普遍的愿意是因为IO操作,无论是磁盘IO还是网络IO都是很慢的。线程在执行中会等待,因此效率就下来了。这也就是为什么在一个物理核上执行多个线程会感觉效率高了,对于程序调度来说,一个线程等待时,也正是其它线程执行的大好机会,因此,CPU资源得到了充分的利用。 

2.尽可能不要挂起线程

多线程程序免不了要同步,最直接的方法就是使用锁。每次只允许一个线程进入临界区,让其它相关线程等待。等待有2种,一种是直接使用操作系统指令挂起线程,另外一种是自旋等待。在操作系统直接挂起,是一种简单粗暴的实现,性能较差,不太适用于高并发的场景,因为随之而来的问题就是大量的线程上下文切换。如果可以,尝试一下进行有限的自旋等待,等待不成功再去挂起线程也不迟。这样很有可能可以避免一些无谓的开销。JDK中ConcurrentHashMap的实现里就有一些自旋等待的实现。此外Java虚拟机层面,对synchronized关键字也有自旋等待的优化。 

3.善用“无锁”

阻塞线程会带来性能开销,因此,一种提供性能的方案就是使用无锁的CAS操作。JDK中的原子类,如AtomicInteger正是使用了这种方案。在高并发环境中,冲突较多的情况下,性能远远好于传统的锁操作。

4.处理好“伪共享”问题

CPU有一个高速缓存Cache。在Cache中,读写数据的最小单位是缓存行,如果2个变量存在一个缓存行中,那么在多线程访问中,可能会相互影响彼此的性能。因此将变量存放于独立的缓存行中,也有助于变量在多线程访问是的性能提升,大量的高并发库都会采用这种技术。

推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式