2017-09-27 12 views
1

私は、複数の反復で動作するプログラムを持っています。 各ループでは、最大3000個の同時スレッドを開始しています。その中のいくつかは反復中に開始し、反復の終了前に終了し、そのうちのいくつかは起動され、反復の終了時まで生き続ける。Javaスレッドプール - どのタイプと数ですか?

スレッドごとに繰り返します。

  1. FixedThreadPoolはどのタイプのエクゼキュータを使うべきですか? ThreadPoolExecutor?その他?
  2. 最大値、最小値、固定値、その他の値のスレッド数を設定する必要がある場合はどうすればよいですか?
  3. ステータスを追跡するために、各スレッドのサブミッションごとに新しいFutureオブジェクトを作成する必要がありますか?

最初、私は通常FixedThreadPoolを使用し、スレッドの最高数は通常、マシン内のコア数(Runtime.getRuntime().availableProcessors())は、あなたの質問に答えるために感謝

答えて

1

同時スレッド数は現在のハードウェアにとっては高すぎます。プールのサイズは、ハードウェアの能力(CPUコアの数)を反映する必要があります。最適な結果を得るためには、さまざまなサイズで試す必要がありますが、3000スレッドの同時スレッドでは、それらを飢えさせるだけです。

必要なのは、ループ内でタスクを追加するキューと、キューから引き出してタスクを実行するワーカースレッドを利用することです。ワーカースレッドは限られたサイズのスレッドプールに入ります。

したがって、指定されたキューで動作するThreadPoolExecutorが確実に必要です。 javadoc of the classには、キューイングの戦略に関する有用な情報があります。

+0

ありがとうシャロン。 1. maximumPoolSizeのThreadPoolExecutor ctor引数をavailableProcessors()の値に設定することをお勧めしますか?私は実際に任意のスレッドの種類のプールを使用できますか? 3. qn 2に続いて、プールをシングルトンオブジェクトとして定義することが賢明でしょうか?私が言ったように – dushkin

+1

、プールのサイズは多くの要因に依存します。最適な結果を得るためには実験を行う必要があります。 availableProcessorsから始めることができ、試行錯誤して調整することができます。エグゼキュータはシングルトンにすることができます。 (またはパブリック静的var) –

1

新しいFutureオブジェクトを作成するには、それが依存します。あとでデータを収集する必要がある場合は、もちろん、未来が必要ですか?

拡張子として、私はForkJoinPoolを調べることをお勧めします。これは、作業を分割し、結果を組み立て直すためのタスクの一種です。

1

スレッド数に関する計算(最小/最大など)はそれほど正確ではなく、作業負荷とハードウェアに関する知識が必要です。たとえば、タスクが完全にCPUバウンドの場合、理論的には、スレッド番号=コア数となります。一方、スレッドがIOバウンド(たとえば、データベースやネットワークなどの呼び出し)の場合、この数値は大きくなります。また、システム上で実行されているユーザーレベルのアプリケーションやデフォルトのOSプロセスを考慮する必要があります。 Javaの各スレッドには、それに関連付けられたスタックメモリがあり、スレッド数で累積します。別の要因は、メモリに追加されるスレッドプールのタスクキューのサイズです。最高のアドバイスは、利用可能なコアの数で始めることができますRuntime.getRuntime().availableProcessors()スレッドとプロファイル。おそらく、あなたのパフォーマンス/スループットが最大である番号に到着し、次にそれが下降するスレッド番号をさらに増加させるでしょう。

関連する問題