12

Javaドキュメントから、

ForkJoinPool が他の種類の ExecutorService と異なるのは、主にワーク スティーリングを採用している点です。プール内のすべてのスレッドは、他のアクティブなタスクによって作成されたサブタスクを見つけて実行しようとします (存在しない場合は、最終的にワークの待機をブロックします)。

これにより、ほとんどのタスクが他のサブタスクを生成するときに効率的な処理が可能になります (ほとんどの ForkJoinTask がそうであるように)。コンストラクターで asyncMode を true に設定する場合、ForkJoinPools は、決して結合されないイベント スタイルのタスクでの使用にも適している場合があります。

以下のForkJoinPool の例を見た後、ThreadPoolExecutor とは異なり、キュー サイズを設定するパラメーターは見当たりませんでした。ForkJoinPool がどのようにメカニズムを盗むかについての手がかりは得られませんでした。

//creating the ThreadPoolExecutor

ThreadPoolExecutor executorPool = new ThreadPoolExecutor(2, 10, 60, TimeUnit.SECONDS, 
new ArrayBlockingQueue<Runnable>(3000), threadFactory, rejectionHandler);

10 個のスレッドで ThreadPoolExecutor を作成し、3000 個の Callable タスクが送信されたとします。これらのスレッドは、サブタスクの実行負荷をどのように共有していますか?

また、ForkJoin プールは同じユースケースでどのように異なる動作をしますか?

4

2 に答える 2

17

事前に 3000 のタスクがあり、それらが他のタスクを生成しない場合、2 つの動作に大きな違いはありません。10 スレッドの場合、10 個のタスクがすべて完了するまで一度に実行されます。

ForkJoinPool は、開始するタスクが 1 つまたはいくつかあるが、そのタスクが自分自身をサブタスクに分割する方法を知っている場合のために設計されています。この状況では、ForkJoinPool は、タスクが処理スレッドの可用性をチェックし、適切に分割できるように最適化されています。

于 2015-10-31T18:31:36.470 に答える