Java 7で導入されたFork/Joinフレームワークの実装について読みましたが、私は魔法の仕組みを理解していることを確認したかったのです。javaフォーク/スタック使用についての明確化
私が理解しているように、スレッドがフォークすると、そのキューにサブタスクが作成されます(他のスレッドが盗むこともあれば盗むこともありません)。スレッドが「結合」しようとすると、実際にそのキューに既存のタスクがあるかどうかがチェックされ、再帰的に実行されます。つまり、「結合」操作の場合、スレッドコールスタックに2つのフレームが追加されます新しい取られたタスク呼び出しのために)。
私はJVMがテールコールの最適化をサポートしていないことを知っています(このような状況ではjoinメソッドスタックフレームを削除することができます)。フォークを多数使用して複雑な操作を実行しているときに、 StackOverflowError
。
私はそうですか、それともそれを防ぐためのクールな方法を見つけましたか? (簡略化のため) セイ我々は唯一forkjoinプール内の1つのスレッドを持っている:
EDITここ
は質問を明確にするのに役立つシナリオです。 ある時点で、スレッドは分岐してからjoinを呼び出します。結合メソッド中に、スレッドはforkされたタスク(キュー内にある)を実行できることを検出して、次のタスクを呼び出します。このタスクは順番に分岐してjoinを呼び出します。つまり、joinメソッドを実行している間にスレッドは(以前と同じように)キュー内のforkされたタスクを見つけ出し、呼び出します。その段階で を呼び出しスタックには、少なくとも2つのジョインと2つのタスクのフレームが含まれます。
フォーク結合フレームワークがプレーンな再帰に変換されているのが分かります。 Javaではテールコールの最適化がサポートされていないため、Javaのすべての再帰で十分な深さになるとStackOverflowError
が発生する可能性があります。
私の質問は、フォーク/結合フレームワークの実装者は、この状況を防ぐためのクールな方法を見つけましたか?
あなたがポイントを惜しまないかどうか確かめてください。 – bennyl