ForkJoinPoolを使用 して、CPU を集中的に使用する計算を並列化しようとしています。ForkJoinPool についての私の理解では、タスクを実行できる限り機能し続けるということです。残念ながら、ワーカー スレッドがアイドリング/待機していることを頻繁に観察したため、すべての CPU がビジー状態に保たれているわけではありません。追加のワーカー スレッドを観察することさえありました。
非ブロッキングタスクを厳密に使用しようとしたため、これは予期していませんでした。私の観察は、 ForkJoinPool がスレッドを無駄にしているように見えるのと非常によく似ています。ForkJoinPool に多くのデバッグを行った後、推測があります。
サブタスクのリストに作業を分散するために、invokeAll() を使用しました。invokeAll() が最初のタスク自体の実行を終了した後、他のタスクへの参加を開始します。参加する次のタスクが実行中のキューの一番上に来るまで、これは正常に機能します。残念ながら、追加のタスクに参加せずに非同期で送信しました。私は、ForkJoin フレームワークが最初にこれらのタスクを実行し続けてから、残りのタスクの結合に戻ることを期待していました。
しかし、この方法ではうまくいかないようです。代わりに、待機中のタスクの準備が整うまで (おそらく他のワーカー スレッドによって実行される)、ワーカー スレッドは wait() の呼び出しを停止します。私はこれを確認しませんでしたが、join() を呼び出す一般的な欠陥のようです。
ForkJoinPool は asyncMode を提供しますが、これはグローバル パラメーターであり、個々の送信には使用できません。しかし、非同期にフォークされたタスクがすぐに実行されるのが好きです。
では、なぜ ForkJoinTask.doJoin() は、準備が整うまで (自分で実行するか、他のユーザーに盗まれるかのいずれか)、キューの一番上にある使用可能なタスクを単純に実行しないのでしょうか?