7

プロジェクトの要件により、今日マルチスレッドプログラミングを学びました。

小さなサブタスクにうまく分割できる文字列処理タスクがあります。

while (...){
    ...
    // assign task for handler
    Thread t = new Thread(new PCHandler(counter,pc));
    t.start();
    counter++;
}

問題は、このタスクに約 500K のスレッドが必要になることです。そして、私はエラーに遭遇します:

原因: java.lang.OutOfMemoryError: 新しいネイティブ スレッドを作成できません

Web を検索したところ、JVM では最大 32K のスレッドしか作成できないようです。プロファイル ファイルを変更してこの制限を拡張する手順がいくつかあります。しかし、ユーザーのコンピューターを変更することは避けたいです。制限内で賢く管理する方法を教えてください。

4

2 に答える 2

24

問題は、このタスクに約 500K のスレッドが必要になることです。[メモリ エラー] が発生しました。

スレッドプールを使用して、多数のジョブを送信できますが、それらを少数のスレッドでしか実行できないように思えます。

// create a thread pool with 10 threads, this can be optimized to your hardware
ExecutorService threadPool = Executors.newFixedThreadPool(10);
// submit your handlers to the thread-pool
for (PCHandler handler : handlersToDo) {
    threadPool.submit(handler);
}
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();
...

これがうまくいかない場合は、実際に 500k の同時実行スレッドを必要とするシステムの詳細を知りたいです。ボックスのメモリ設定を微調整してコアメモリを増やすことでこれを達成できるかもしれませんが、アプリケーションの再構築が適切であると思われます。

@Peter がコメントで言及しているように、プール内のスレッド数を最適化するために、使用可能なプロセッサの数と他のシステム仕様を取得して、これを把握できます。PCHandlerただし、クラスの CPU 使用率に大きく依存します。IO が多いほど、より多くの同時実行性を利用できます。おそらく、メソッドに渡されたさまざまな値を使用していくつかのテストを実行するnewFixedThreadPool(...)のは、最適な設定を決定するためです。

また、500k ジョブ オブジェクトの大きさによっては、作成を制限したい場合があります。これを行うには、任意の時点で未処理のジョブの数を制限する制限付きキューを使用してスレッド プールを作成できます。

于 2013-10-02T13:08:29.823 に答える