【发布时间】:2011-10-12 01:02:16
【问题描述】:
我有一个程序,它通过将大文件分成块、排序块并将它们合并到最终排序的文件中来对大文件进行排序。应用程序运行一个线程来从文件加载/保存数据 - 只有一个线程执行 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/
【问题讨论】:
-
我们可能需要查看您的代码才能弄清楚这一点。我的猜测是你使用的线程比你想象的要多。
-
我使用 jvisualvm 来计算线程数——它只显示我知道的线程。我还做了一个简单的测试程序,它只运行一个主线程并得到完全相同的结果。请查看我有问题的更新。
-
4 线程不能使用 6 核的 100% 利用率。要么你有更多线程,要么你的测量结果有误。
-
您使用什么程序来监控 CPU 使用率?它可能向您展示了在后台运行的其他一些程序。要么是这样,要么你的测试太短了,它只向你展示了一些与 JVM 启动相关的东西。
-
我使用 nmon 来监控 CPU 利用率,这里是屏幕截图:link 另外,虽然我没有运行 java 程序 - 它没有显示任何活动。无论如何,我在运行我原来的排序程序时看到的完全一样。老实说,我所期待的正是每个人所期望的——一个线程使用一个 CPU。但看起来 java 使用未链接到底层操作系统线程的绿色线程。据我了解,java 使用自己的线程调度。因此,它可能会导致多个本机线程服务于一个 java 线程???
标签: java multithreading multicore utilization