我有一个程序,它通过将大文件分成块、对块进行排序并将它们合并到最终排序的文件中来对它们进行排序。应用程序运行一个线程来从文件加载/保存数据 - 只有一个线程执行 I/O 操作。还有另外两个线程接收块数据,对其进行排序,然后将排序后的数据发送回执行 I/O 的线程。
所以通常有 4 个线程在运行——主线程、加载/保存数据的线程和两个对数据进行排序的线程。
我想在执行期间我会看到 1 个不占用任何 CPU 时间的休眠线程(主线程)和 3 个每个使用 1 个 CPU 内核的活动线程。
当我在具有超线程(24 个 CPU)的双 6 核处理器机器上运行该程序时,我看到所有 24 个 CPU 的加载率为 100%!
最初我认为排序算法是多线程的,但在查看 java 源代码后我发现它不是。
我正在使用简单的 Collections.sort(LinkedList) 对数据进行排序......
以下是一些细节:
# java -版本 java版本“1.6.0_26” Java(TM) SE 运行时环境 (build 1.6.0_26-b03) Java HotSpot(TM) 64 位服务器 VM(内部版本 20.1-b02,混合模式) # unname -a Linux 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/