我有一个程序,通过将大文件分成块,对块进行排序,并将它们合并到最终排序的文件中。应用程序运行一个线程从文件中加载/保存数据-只有一个线程进行I/O操作。另外还有两个线程接收块数据,对其进行排序,然后将排序后的数据发送回执行I/o的线程
所以通常有4个线程在运行-主线程,加载/保存数据的线程和两个排序数据的线程。
我认为在执行期间,我会看到1个睡眠线程(main),不占用任何CPU时间和3个活动线程,每个线程利用1个CPU核心。
当我在双6核超线程(24个CPU)处理器机器上运行这个程序时,我看到所有24个CPU都被100%加载!
最初我认为排序算法是多线程的,但在查看java源代码后,我发现它不是。
我使用简单的Collections.sort(LinkedList)来排序数据…
下面是一些细节:
<>之前# Java -versionJava版本"1.6.0_26"Java(TM) SE运行环境(build 1.6.0_26-b03)Java HotSpot(TM) 64位服务器VM (build 20.1-b02,混合模式)# uname -aLinux 2.6.32-28-server #55-Ubuntu SMP Mon Jan 10 23:57:16 UTC 2011 x86_64 GNU/Linux之前我正在使用nmon来监视处理器加载。
我将感谢任何解释这种情况和任何建议如何控制CPU负载,因为这个特定的任务不会为其他应用程序留下CPU时间
(更新)我使用jvisualvm来计算线程数——它只显示我知道的线程。我还做了一个简单的测试程序(见下文),只运行一个主线程,并得到完全相同的结果-所有24个处理器在代码执行期间几乎100%繁忙
public class Test {
public void run(){
Random r = new Random();
int len = r.nextInt(10) + 5000000;
LinkedList<String> list = new LinkedList<String>();
for (int i=0; i<len; i++){
list.add(new String("test" + r.nextInt(50000000)));
}
System.out.println("Inserted " + list.size() + " items");
list.clear();
}
public static void main(String[] argv){
Test t = new Test();
t.run();
System.out.println("Done");
}
}
(更新)下面是我在运行上面的程序(使用nmon)时所做的截图:http://imageshack.us/photo/my-images/716/cpuload.png/
我建议,这是一个非java问题,而不是java问题,为了解决这个问题,我将看一下top
命令,它提供了关于每个进程的cpu使用情况的信息。我预测的结果如下:您将看到一个java线程使用接近100%的cpu时间(这很好,因为top中的每个进程百分比相对于一个(虚拟)核心),也许第二个和第三个java线程的cpu使用要少得多(I/O线程)。根据gc的选择,您甚至可能发现一个或多个gc- thread,但远少于20个。
HotSpot不会(据我所知甚至不能)自己并行化顺序任务。