2

我有一个程序,它通过将大文件分成块、对块进行排序并将它们合并到最终排序的文件中来对它们进行排序。应用程序运行一个线程来从文件加载/保存数据 - 只有一个线程执行 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/

4

1 回答 1

1

我建议,这是一个 nmon 而不是 java 问题,为了解决它,我会看一下该top命令,它提供有关每个进程的 cpu 使用情况的信息。我预测以下结果:您将看到一个 java 线程使用接近 100% 的 cpu 时间(这没关系,因为顶部的每个进程百分比相对于一个(虚拟)核心),可能是第二个和第三个 java 线程有很多更少的 cpu 使用(I/O 线程)。根据 gc 的选择,您甚至可能会发现一个或多个 gc-Threads,但远少于 20 个。

然而,HotSpot 不会(据我所知甚至不能)自行并行化顺序任务。

于 2011-10-13T19:16:47.533 回答