当前位置:  开发笔记 > 编程语言 > 正文

并行化:除了同步和I/O之外,是什么导致Java线程阻塞?

如何解决《并行化:除了同步和I/O之外,是什么导致Java线程阻塞?》经验,为你挑选了1个好方法。

简短版本在标题中.

长版:我正在开发一个使用Java进行科学优化的程序.程序的工作量可以分为并行和串行阶段 - 并行阶段意味着正在执行高度可并行化的工作.为了加速程序(它运行数小时/天),我创建了许多线程,这些线程等于我正在使用的机器上的CPU核心数 - 通常是4或8 - 并在它们之间划分工作.然后我开始这些线程并加入()它们,然后再进入串行阶段.

到现在为止还挺好.令我困扰的是,并行阶段的CPU利用率和加速量远远没有达到"理论最大值" - 例如,如果我有4个核心,我预计会看到350-400%"利用率"(如上图所示)但它反而在180到310之间反弹.仅使用一个线程,我获得100%的CPU利用率.

我知道线程不能全速运行的唯一原因是:由于同步导致的I/O阻塞造成的阻塞

在我的并行线程中没有任何I/O,也没有任何同步 - 线程共享的唯一数据结构是只读的,并且是基本类型或(非并发)集合.所以我正在寻找其他解释.一种可能性是多个线程反复阻塞垃圾收集,但这在内存压力的情况下似乎才有意义,而且我的分配远远高于所需的最大堆空间.

任何建议,将不胜感激.

更新:万一有人好奇,经过一些调查后,我调整了代码以获得一般性能并且看到更好的利用率,即使我改变的任何事情都与同步有关.但是,一些更改应该导致更少的新堆分配,特别是我摆脱了一些迭代器临时盒装数字的使用(用于高性能Java计算的CERN"Colt"库在这里很有用:它提供了像IntArrayList这样的集合,DoubleArrayList等基本类型.).所以我认为垃圾收集可能是罪魁祸首.



1> krosenvold..:

所有图形操作都在单个线程上运行.如果他们渲染到屏幕,他们将有效地争夺对该线程的访问权.

如果您在Windows上运行,则无论如何,所有图形操作都在单个线程上运行.其他操作系统也有类似的限制.

实际上,有时候很难获得适当的线程工作者粒度,有时很容易使它们太大或太小,这通常会使所有内核的使用率低于100%.

如果你没有渲染太多gui,那么最可能的罪魁祸首就是你对某些共享资源的争论比你想象的要多.使用jprofiler等分析器工具很容易看到这一点.有些VM就像bea的jrockit甚至可以直接告诉你这个.

这是你不想做出猜测的地方之一.获取一个分析器!

推荐阅读
U友50081205_653
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有