大きなファイルをチャンクに分割し、チャンクをソートして最終的なソート済みファイルにマージするプログラムがあります。アプリケーションは、ファイルとの間でデータをロード/保存するために 1 つのスレッドを実行します。1 つのスレッドのみが I/O 操作を行います。また、チャンク データを受信し、並べ替えてから、並べ替えたデータを I/O を実行するスレッドに送り返す 2 つのスレッドがあります。
したがって、一般に、メインスレッド、データをロード/保存するスレッド、およびデータを並べ替える 2 つのスレッドの 4 つのスレッドが実行されています。
実行中に、CPU 時間をまったく使用しない 1 つのスリープ スレッド (メイン) と、それぞれ 1 つの CPU コアを使用する 3 つのアクティブなスレッドが表示されると思いました。
ハイパー スレッディング (24 CPU) を備えたデュアル 6 コア プロセッサ マシンでこのプログラムを実行すると、24 個すべての CPU が 100% ロードされていることがわかります。
最初はソートアルゴリズムがマルチスレッド化されていると思っていましたが、Java ソースを調べたところ、そうではないことがわかりました。
私は単純な Collections.sort(LinkedList) を使用してデータをソートしています...
ここにいくつかの詳細があります:
# Java バージョン Java バージョン「1.6.0_26」 Java(TM) SE ランタイム環境 (ビルド 1.6.0_26-b03) Java HotSpot(TM) 64 ビット サーバー VM (ビルド 20.1-b02、混合モード) # うなめ -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 を使用してスレッドをカウントしました - 知っているスレッドのみが表示されます。また、メイン スレッドを 1 つだけ実行する簡単なテスト プログラム (以下を参照) を作成し、まったく同じ結果を得ました。コード実行中、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/