DelayQueue の実際の使用法は何ですか?解決するために設計された一般的な問題は何ですか?
最近、レート制限に遅延キューを使用しました。
1秒あたりのイベント数をXに制限するには、各イベントを1秒の遅延を持つ遅延キューに配置します。
DelayQueueにXイベントがある場合、キューからtake()を実行します(少なくとも1つが期限切れになるまでブロックします)。これにより、長期的な制限を超えることなく、短期的なバーストを許可できます。
このクラスは、複数の遅延イベントを適切な順序で処理したいスレッドに最適です。
たとえば、100個のライトが点滅しているディスプレイがあり、すべてのライトが無関係な速度で点滅しているとします。ライトごとにスレッドを作成することも、このクラスを使用して1つのスレッドですべてのライトを調整することもできます。次のように機能します。
Light
クラスがあるDelayed
インターフェイスの実装を作成します。たとえば、LightFlash
DelayQueue
を作成し、ライトごとに新しいLightFlash
を追加します。ライトのフラッシュレートに適した遅延を設定しますDelayQueueは、処理する次のイベントを取得します。
私が考えることができる2つの実際の例:
DelayQueue
はおそらく priority queue として実装されますが、これは一般的に heap として実装するのが最適です。
主な使用法は、for Timerクラスのようなタスクタイマーです。
遅延をシステムクロックから独立させることができる場合(私は信じられますが、確信が持てません)、「5ティックがXに移動した後」などのゲームイベントにそれを使用できます(そうでない場合、クロックジッタが発生すると、これは信頼できなくなります)。
遅延は、キュー自体ではなく、キューに入る要素に関連付けられていることに注意してください。キューに入るいくつかのオブジェクトはゼロの遅延を持つことができますが、いくつかははるかに長い遅延を持つことができます:
http://docs.Oracle.com/javase/6/docs/api/Java/util/concurrent/Delayed.html
これを念頭に置いて、いくつかの使用例を考えることができます。ただし、おそらくそれらは壊れやすく、メッセージングフローに関しては少しコードのにおいがします。特定の状況を除いて、それらすべての代替手段を使用します。
1)制御フロー-注文の処理には60秒かかることがわかっているため、オブジェクトが少なくとも60秒間存在するまで、キューから次の注文を読み取らないでください。
2)メッセージフロー-高度に非同期のシステムで、2つまたは3つの外部サービスに要求を送信し、次のタスクをリリースして、N秒後に最初のジョブのバッチに少なくとも完了のチャンス。
3)メッセージのバッチ処理-おそらく特定のタイプの注文はバースト性があるため、最後のN秒間に受信した注文を処理しないで、次の実行でバッチとして処理できる直後に同様の注文が来るかどうかを確認します。
4)メッセージの優先度-異なるメッセージまたは異なる顧客は、遅延が少ないかゼロのわずかに高いサービス品質を得ることができます。
場合によっては、キューに配置したオブジェクトは、デキューの準備ができる前に、そのキューに一定時間置かれる必要があります。これは、BlockingQueueインターフェースを実装するJava.util.concurrent.DelayQueueクラスを使用する場所です。 DelayQueueでは、キューオブジェクトが指定された時間キューに常駐している必要があります。
実際の使用例については、devxサイトの Minding the Queue の記事を参照してください
...これを説明するために私が考えた実世界の例(あなたが空腹になるかもしれない)は、マフィンを含みます。まあ、マフィンオブジェクト(Javaについて話しているように、コーヒーのしゃれは意図されていません)。 Muffinオブジェクトを配置するDelayQueueがあるとします... getDelayメソッドは、本質的に、オブジェクトがDelayQueueに保持される残り時間を示します。このメソッドによって返される数がゼロまたはゼロ未満になると、オブジェクトは準備完了(またはこの例ではベイク)になり、デキューが許可されます...
完全に調理されていないマフィンを本当に食べたくないので、マフィンをDelayQueueに置いて、推奨される調理時間を確保してください...