2

同じスレッドでN 個のタスクを実行する必要があるとします。タスクでは、外部ストレージからの値が必要になる場合があります。どのタスクがいつそのような値を必要とするかは事前にわかりません。Mクエリで同じM値を外部ストレージにフェッチするよりも、一度にM値をフェッチする方がはるかに高速です。

タスク自体からの連携は期待できないことに注意してください。タスクは単なる java.lang.Runnable オブジェクトと見なすことができます。

さて、理想的な手順は、私が見ているように、次のようになります

  1. すべてのタスクをループで実行します。タスクが外部値を要求する場合は、これを覚えておいて、タスクを中断 して次のタスクに切り替えてください。
  2. 前のステップで要求された値を一度にフェッチします。
  3. 完了したすべてのタスクを削除します (中断されたタスクは完了したと見なされません)。
  4. まだタスクが残っている場合は、手順 1 に進みますが、タスクを実行するのではなく、中断された状態から実行を続けます。

私が見る限り、何かを「一時停止」および「再開」する唯一の方法は、関連するフレームを JVM スタックから削除し、それらをどこかに保存し、後でそれらをスタックに戻して JVM を続行させることです。

これを行うための標準的な (JVM バイトコードよりも低いレベルでのハッキングを含まない) 方法はありますか?

または、これを達成するための別の方法を提案できますか ( Nスレッドを開始するか、タスクを何らかの方法で連携させる以外に)。

4

3 に答える 3

1

前述のように、Quasarはバイトコード変換を使用して、まさにそれを行います (通常は M スレッドで N ファイバーをスケジュールしますが、M を 1 に設定できます)。各タスク (別名「ファイバー」) に独自のスタック トレースを与えることもできるため、スレッドを共有している他のタスクから干渉を受けることなく、それをダンプして完全なスタック トレースを取得できます。

于 2015-02-17T15:19:28.063 に答える