web-dev-qa-db-ja.com

Spring ThreadPoolTask​​ExecutorのcorePoolSizeとmaxPoolSizeの違いは何ですか

MassEmailをWebサイトのすべてのユーザーに送信する必要があります。送信されるメールごとにスレッドプールを使用したい。現在、私は値を次のように設定しています:

<property name="corePoolSize" value="500" />
<property name="maxPoolSize" value="1000" />

2つの違いは何ですか?現在私は約持っています。 10000ユーザー。

37
rabbit

javadocはそれを最もよく言っています

新しいタスクが送信され[...]、実行中のスレッドがcorePoolSize未満の場合、他のワーカースレッドがアイドル状態であっても、リクエストを処理するために新しいスレッドが作成されます。実行中のスレッドがcorePoolSizeより多いがmaximumPoolSizeより少ない場合、キューがいっぱいの場合にのみ、新しいスレッドが作成されます。 corePoolSizemaximumPoolSizeを同じに設定することで、固定サイズのスレッドプールを作成します。 maximumPoolSizeInteger.MAX_VALUEなどの本質的に無制限の値に設定することで、プールが任意の数の並行タスクに対応できるようになります。

特定の状況については、500のメールを同時に送信しても意味がありません。メールサーバーを圧倒するだけです。大量の電子メールを送信する必要がある場合は、単一のスレッドを使用して、一度に1つずつパイプで送信します。メールサーバーは、これを500の個別の接続よりもはるかに適切に処理します。

43
skaffman

スレッド作成に関するSunのルールを簡単に説明します。

  1. スレッドの数がcorePoolSize未満の場合は、新しいスレッドを作成して新しいタスクを実行します。
  2. スレッドの数がcorePoolSizeと等しい(またはそれより大きい)場合、タスクをキューに入れます。
  3. キューがいっぱいで、スレッドの数がmaxPoolSize未満の場合は、タスクを実行する新しいスレッドを作成します。
  4. キューがいっぱいで、スレッドの数がmaxPoolSize以上の場合、タスクを拒否します。

記事全体

元の答え

29
taynguyen

corePoolSizeは、プールで使用されるスレッドの最小数です。数はmaxPoolSizeまで増加できます。負荷が低下すると、プールはcorePoolSizeに縮小されます。

メールの送信は、I/Oバウンド操作のようです。スレッド数が500になっても処理が速くなるとは思いません。

19
Thilo

corePoolSizeまたはmaxPoolSizeの値を増やすよりも、queueCapacityの値を増やすことを検討する必要があります。これら2つのプロパティ(* PoolSize)は実行するプールの数ですが、各メッセージはqueueCapacityで考慮されます。

<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="queueCapacity" value="1000" />
<property name="waitForTasksToCompleteOnShutdown" value="true"/>

送信するユーザーが10000人いる場合、1000 * 10(maxPoolSize)= 10000ですが、スレッドごとに1000が重い場合は、poolSizeを増やすことを検討できます。

4
Osify

@ -skaffmanが official docs から指摘したことに加えて、以下はこれらのサイズがどのように利用されるかをより明確にします:

BlockingQueueは、送信されたタスクの転送と保持に使用できます。このキューの使用は、プールのサイズ設定と相互作用します。

  • 実行中のスレッドがcorePoolSizeより少ない場合、Executorは常に、キューイングよりも新しいスレッドの追加を優先します。
  • corePoolSize以上のスレッドが実行されている場合、Executorは常に、新しいスレッドを追加するのではなく、要求をキューに入れることを優先します。
  • リクエストをキューに入れることができない場合、これがmaximumPoolSizeを超えない限り、新しいスレッドが作成されます。この場合、タスクは拒否されます。
0
Mahesha999

誰もが明確に説明したことは正しいです。ここで気付くことはほとんどありません。コアプールとキューのサイズには常に制限があるはずです。 core-pool-sizeが非常に高い場合、max-pool-sizeに達するまですべてのリクエストに対して新しいスレッドが作成されるため、プールからのスレッドの多くが一定期間未使用のままになる可能性が高くなります。

ただし、マシンが多数のリクエストに同時に直面する場合は、マシンのサイズが十分であることも考慮する必要があります。例:

マシンのサイズが1 GBでキュー容量がInteger.MAX_VALUEの場合、JVM GUIツールで監視できるOutOfMemoryが原因で、マシンが要求を拒否し始める可能性が高くなります。

0
SinhaOjas