web-dev-qa-db-ja.com

DelayQueueの実際の使用法

DelayQueue の実際の使用法は何ですか?解決するために設計された一般的な問題は何ですか?

18
Eran Medan

最近、レート制限に遅延キューを使用しました。

1秒あたりのイベント数をXに制限するには、各イベントを1秒の遅延を持つ遅延キューに配置します。

DelayQueueにXイベントがある場合、キューからtake()を実行します(少なくとも1つが期限切れになるまでブロックします)。これにより、長期的な制限を超えることなく、短期的なバーストを許可できます。

8
Andrew Hill

このクラスは、複数の遅延イベントを適切な順序で処理したいスレッドに最適です。

たとえば、100個のライトが点滅しているディスプレイがあり、すべてのライトが無関係な速度で点滅しているとします。ライトごとにスレッドを作成することも、このクラスを使用して1つのスレッドですべてのライトを調整することもできます。次のように機能します。

  • フラッシュレートが設定されたLightクラスがある
  • ライトを指すDelayedインターフェイスの実装を作成します。たとえば、LightFlash
  • DelayQueueを作成し、ライトごとに新しいLightFlashを追加します。ライトのフラッシュレートに適した遅延を設定します
  • ループ:
    • DelayQueue :: take() でイベントを取得します。
    • ライトのオン/オフを切り替えます
    • DelayQueue :: put(E) を使用して、ライトの次のフラッシュのキューに新しいイベントを追加します。

DelayQueueは、処理する次のイベントを取得します。

私が考えることができる2つの実際の例:

  • 特定の時限アクションを実行する必要がある(非マルチスレッド)サーバー。接続ごとに接続ping。
  • setInterval() および setTimeout() で作成された任意の数の時限イベントを処理する必要のある、JavaScript対応ブラウザーの実装。ああ、アニメーションGIF。

DelayQueueはおそらく priority queue として実装されますが、これは一般的に heap として実装するのが最適です。

10
Michael Slade

主な使用法は、for Timerクラスのようなタスクタイマーです。

遅延をシステムクロックから独立させることができる場合(私は信じられますが、確信が持てません)、「5ティックがXに移動した後」などのゲームイベントにそれを使用できます(そうでない場合、クロックジッタが発生すると、これは信頼できなくなります)。

3
ratchet freak

遅延は、キュー自体ではなく、キューに入る要素に関連付けられていることに注意してください。キューに入るいくつかのオブジェクトはゼロの遅延を持つことができますが、いくつかははるかに長い遅延を持つことができます:

http://docs.Oracle.com/javase/6/docs/api/Java/util/concurrent/Delayed.html

これを念頭に置いて、いくつかの使用例を考えることができます。ただし、おそらくそれらは壊れやすく、メッセージングフローに関しては少しコードのにおいがします。特定の状況を除いて、それらすべての代替手段を使用します。

1)制御フロー-注文の処理には60秒かかることがわかっているため、オブジェクトが少なくとも60秒間存在するまで、キューから次の注文を読み取らないでください。

2)メッセージフロー-高度に非同期のシステムで、2つまたは3つの外部サービスに要求を送信し、次のタスクをリリースして、N秒後に最初のジョブのバッチに少なくとも完了のチャンス

3)メッセージのバッチ処理-おそらく特定のタイプの注文はバースト性があるため、最後のN秒間に受信した注文を処理しないで、次の実行でバッチとして処理できる直後に同様の注文が来るかどうかを確認します。

4)メッセージの優先度-異なるメッセージまたは異なる顧客は、遅延が少ないかゼロのわずかに高いサービス品質を得ることができます。

2

場合によっては、キューに配置したオブジェクトは、デキューの準備ができる前に、そのキューに一定時間置かれる必要があります。これは、BlockingQueueインターフェースを実装するJava.util.concurrent.DelayQueueクラスを使用する場所です。 DelayQueueでは、キューオブジェクトが指定された時間キューに常駐している必要があります。

実際の使用例については、devxサイトの Minding the Queue の記事を参照してください

...これを説明するために私が考えた実世界の例(あなたが空腹になるかもしれない)は、マフィンを含みます。まあ、マフィンオブジェクト(Javaについて話しているように、コーヒーのしゃれは意図されていません)。 Muffinオブジェクトを配置するDelayQueueがあるとします... getDelayメソッドは、本質的に、オブジェクトがDelayQueueに保持される残り時間を示します。このメソッドによって返される数がゼロまたはゼロ未満になると、オブジェクトは準備完了(またはこの例ではベイク)になり、デキューが許可されます...

完全に調理されていないマフィンを本当に食べたくないので、マフィンをDelayQueueに置いて、推奨される調理時間を確保してください...

1
Shree