Javaのいくつかのブロッキングキュー

Javaのいくつかのブロッキングキュー

JavaのBlockingQueueインターフェースは、スレッドセーフなアクセスキューであり、プロデューサーおよびコンシューマーアプリケーションのシナリオに適しており、次の2つの追加操作をサポートします。

  • プロデューサースレッドは、キューがいっぱいになるまでデータをブロッキングキューに入れ続けます。キューがいっぱいになると、プロデューサースレッドはブロックし、コンシューマースレッドがデータをフェッチするのを待ちます。
  • コンシューマスレッドは、キューが空になるまで、ブロッキングキューからデータをフェッチし続けます。キューが空になると、コンシューマースレッドはプロデューサースレッドがデータを配置するのを待機するのをブロックします。

BlockingQueueインターフェース

BlockingQueue4つの異なる処理方法を提供します。

  例外をスローする 特別な値を返す ブロックし続ける タイムアウト終了
挿入方法 add(o) オファー(o) put(o) オファー(o、タイムアウト、時間単位)
除去方法 remove(o) poll() take(o) poll(o、timeout、timeunit)
検査方法 素子() ピーク()
  1. 例外をスローします
    • 追加:データを挿入するときに、ブロッキングキューがいっぱいの場合、例外IllegalStateExceptionスローされます。それ以外の場合、挿入は正常に返されtrueます。容量制限キューを使用してキューをブロックする場合は、このoffer方法を使用することをお勧めします
      • IllegalStateException -容量制限のため、現時点で要素を追加できない場合
      • ClassCastException -指定された要素のクラスにより、この要素がこのキューに追加されない場合
      • NullPointerException -指定された要素がnullの場合
      • IllegalArgumentException -指定された要素の一部のプロパティにより、この要素がこのキューに追加されない場合
    • remove:データを削除するときに、このデータがキューにある場合、削除は正常trueに返されfalseます。それ以外の場合は返されます。1つ以上のオブジェクトが含まれている場合は、1つだけ削除して、を返しtrueます。注意:それはremove(o)あるBlockingQueue方法remove()Queueインターフェース、それはある方法インターフェース。
    • 要素:キューが空の場合、例外がスローされNoSuchElementExceptionます。キューが空でない場合、キュークエリの先頭はデータを返しますが、データは削除しません。これはremove()element同じQueueインターフェイスの方法とは異なります。
  2. 特別な値を返します
    • オファー:データを挿入するときに、ブロッキングキューがいっぱいでない場合、挿入は成功してtrue戻りfalseます。それ以外の場合は返されます。制限付き(容量制限キュー)ブロッキングキューを使用するoffer場合は、例外をスローするaddメソッドではなく、メソッドを使用することをお勧めします
    • ポーリング:このメソッドはQueueインターフェースです。キューが空でない場合は、キューのhead要素をクエリして削除し、返します。キューが空の場合は、を返しnullます。
    • peek:このメソッドはQueueインターフェースです。キューが空の場合は、を返します。nullこれは異なりpollます。キューが空でない場合、クエリはキューの先頭にあるデータを返しますが、データは削除しませんremove()これは異なります。
  3. 常にブロックされています:
    • put:データを挿入するときに、キューがいっぱいの場合はブロッキング待機キューが使用可能であり、待機期間中に中断された場合はスローされInterruptedExceptionます。
    • take:キューのhead要素を照会、削除、および返します。キューが空の場合は、ブロックしている待機キューを使用できます。待機期間中に中断された場合は、をスローしInterruptedExceptionます。
  4. タイムアウト後に終了
    • オファー:データを挿入するときに、キューがいっぱいの場合は、キューが使用可能になるまで指定された時間をブロックし、待機期間中に中断された場合は、をスローしInterruptedExceptionます。挿入が成功した場合はを返しtrue、指定した時間後もキューがまだ使用できない場合はを返しfalseます。
    • poll:キューのhead要素を照会、削除、および返します。キューが空の場合、指定された時間ブロックし、キューが使用可能になるのを待ちます。待機期間中に中断された場合は、スローされInterruptedExceptionます。削除が成功した場合は、キューの先頭要素を返しnullます。指定した時間が経過してもキューがまだ使用できない場合は、を返します。

Queuenullをキューに挿入することはできませんNullPointerExceptionそうしないと、nullがスローされます。

Javaでキューをブロックする

JDK7は7つのブロッキングキューを提供します。それぞれ

  • ArrayBlockingQueue:配列構造体で構成される制限付きブロッキングキュー。
  • LinkedBlockingQueue:リンクリスト構造で構成される制限付きブロッキングキュー。
  • PriorityBlockingQueue:優先度の並べ替えをサポートする無制限のブロッキングキュー。
  • DelayQueue:優先キューを使用して実装された無制限のブロッキングキュー。
  • SynchronousQueue:要素を格納しないブロッキングキュー。
  • LinkedTransferQueue:リンクリスト構造で構成される無制限のブロッキングキュー。
  • LinkedBlockingDeque:リンクリスト構造で構成される双方向のブロッキングキュー。

ArrayBlockingQueue

ArrayBlockingQueueこれは、アレイベースの先入れ先出し(FIFO)制限付きブロッキングキューです。

  • キューを作成するときは、キューの容量(容量)、つまり配列のサイズを指定する必要があります。
  • キューを作成するときにCollection、キュー要素を初期化するために渡すことができます。
  • キューが作成されると、キューの容量を変更することはできません。
  • キューはフェアモードとアンフェアモードをサポートし、デフォルトはアンフェアモードです。
  • キューにはロックが1つだけあり、書き込みロックと読み取りロックは分離されておらず、同時実行制御は従来の2条件(notEmptynotFull)アルゴリズムを採用しています。

LinkedBlockingQueue

LinkedBlockingQueueこれは、リンクされたノードの先入れ先出し(FIFO)に基づくオプションで制限されたブロッキングキューです。

  • キューを作成するときに、追加のオーバーヘッドを回避するために、キュー容量を指定できます。キュー容量を指定しない場合、デフォルトのキュー容量はInteger.MAX_VALUEです。
  • キューを作成するときにCollection、キュー要素を初期化するために渡すことができます。現時点では、キュー容量を指定することはできません。デフォルトはInteger.MAX_VALUEです。
  • キューのcount現在使用されているキュー要素の数AtomicIntegerを防止するputtakeの競争。
  • ArrayBlockingQueue違いは、LinkedBlockingQueue読み込みロックと書き込みロックが分離され、キューの中の2つのロックがあること。
  • 使用時にLinkedBlockingQueue、キューサイズがデフォルト値であり、本番速度が消費速度よりも速い場合、メモリオーバーフローが発生する可能性があります。
  • LinkedBlockingQueue理論的にArrayBlockingQueueはスループットが高くなりますが、ほとんどの実際のアプリケーションシナリオでは、パフォーマンスが向上しません。

PriorityBlockingQueue

PriorityBlockingQueueこれは、優先度をサポートする配列ベースの無制限のブロッキングキューです。このキューのデータ構造はヒープです。

  • キューを作成するときに、初期容量(initialCapacity)を指定すると、デフォルトの初期容量DEFAULT_INITIAL_CAPACITYは11になります。
  • キューを作成するときに、キューの容量(容量)ではなく、キューの初期容量(initialCapacity)を指定できます。
  • PriorityBlockingQueueLinkedBlockingQueueオプションの制限付き(オプションで制限付き)に対する無制限(無制限)、無制限とは、キューの作成時にキューの最大容量を指定できないことを意味します。制限がないことPriorityBlockingQueueではありませんLinkedBlockingQueueデフォルト(指定できる、であるこれはデフォルトの容量を示すことに注意してください、Integer.MAX_VALUEよりも大きいが)最大容量はありInteger.MAX_VALUE、かつPriorityBlockingQueue最大容量ですMAX_ARRAY_SIZE=Integer.MAX_VALUE-8
  • PriorityBlockingQueue無制限のもう1つの意味は、キューが無制限であり、フルキャパシティーなどがないため、キューがいっぱいであるためにプロデューサースレッドがブロックされないことです。offer(E e, long timeout, TimeUnit unit)最後の2つのパラメーターは効果がありません。ソースコードを見ると、メソッドの実装が直接呼び出されていることがわかりoffer(e)ます。ただし、キューが空の場合takeでも、ブロックされます。
  • offer(e)決して戻らない、戻らないfalseまたはブロックしoffer(E e, long timeout, TimeUnit unit)ないfalse
  • PriorityBlockingQueueキューは配列を介して実装されます。元の配列がいっぱいになると、配列をコピーしてキューの容量が拡張されます。新しく拡張された配列の容量がを超えるMAX_ARRAY_SIZEOutOfMemoryError、例外がスローされます。
  • デフォルトでは、要素は自然な順序で配置され、要素の並べ替え規則はコンパレータによって指定することもできます。要素は昇順で配置されます。

DelayQueue

DelayQueueこれはPriorityQueue、要素の遅延取得をサポートするブロッキングキューの実装に基づいています。

  • DelayQueueに格納されるオブジェクトは、Delayedインターフェイスを実装する必要があります。
  • 何満了要素が存在しない場合、何も存在しないhead、およびpollメソッド戻りヌルは。
  • 要素のgetDelay(TimeUnit.NANOSECONDS)戻り値が0以下になると、要素は期限切れになります。
  • 有効期限切れてない要素を使用takeおよびpoll削除することはできませんが、これらの有効期限が切れていない要素は、有効期限が切れた要素と同じように扱われます。たとえばsize、メソッドによって返される数量は、期限切れの要素と期限切れの要素の合計です。

DelayQueue該当するシナリオ:

  • アイドル状態のリンクを閉じます。サーバーには多くのアイドルリンクがあり、一定期間後にそれらを閉じます。
  • 期限切れのキャッシュを削除します。一定期間後、キャッシュされたオブジェクトをいくつか削除します。
  • タスクタイムアウト処理。ネットワークプロトコルスライディングウィンドウ要求応答の相互作用で、タイムアウトの応答しない要求を処理します。
  • 注文が生成されてから60秒後、SMS通知がユーザーに送信されます。
  • 注文から15分後、ユーザーが支払いを行わない場合、注文はクローズされます。

上記のいくつかのシーンの例を通して、それが特定の期間の後に特定のビジネス処理DelayQueue行うのに適していることがわかります。

SynchronousQueue

SynchronousQueueデータバッファはありませんBlockingQueue

  • 1つのスレッドの挿入は、別のスレッドの削除操作が完了するのを待つ必要があり、その逆も同様です。
  • SynchronousQueueハンドオフ設計、つまり、あるスレッドで実行されているオブジェクトが特定の情報、タスク、またはイベントを別のスレッドで実行されているオブジェクトに渡す必要があるシナリオに適しています。
  • SynchronousQueue公正および不公正なモデルをサポートします。
  • peek要素は削除しようとしたときにのみ存在するため、同期キューでは実行できません
  • 反復に使用できる要素がないため、キューを反復できません。
  • Executors.newCachedThreadPool()SynchronousQueueキューはで使用されます。

LinkedTransferQueue

LinkedTransferQueueこれは、リンクされたノードに基づく無制限のブロッキングキューです。

  • 無制限キュー(Integer.MAX_VALUE)、入力および出力キューはFIFO(先入れ先出し)の原則を採用しています。
  • プロデューサーは、キューに追加された要素が特定のコンシューマーによって消費されるまでブロックします。これは主にスレッド間のメッセージの送信に使用されます。これSynchronousQueueは非常に似ていSynchronousQueueますそれより優れいます。
  • LinkedTransferQueueこのメソッドを使用して通常の要素追加操作を実行するかBlockingQueue、このputメソッドを使用してtransfer追加をブロックすることができます
  • SynchronousQueue柔軟性と比較して、キューの長さはゼロではなく、ブロック挿入と非ブロック挿入の要素が共存できます。
  • 現在、エレメントの受信を待機しているコンシューマーが存在する場合(コンシューマーがtake()メソッドまたは時間制限のあるメソッドを使用する場合poll())、transferメソッドはプロデューサーから渡されたエレメントをコンシューマーにすぐに転送できます。要素の受信を待機しているコンシューマーがない場合、transferメソッドは要素をキューのtailノードに格納し、要素がコンシューマーによって消費されるまで待機してから戻ります。

LinkedBlockingDeque

LinkedBlockingDueueこれは、リンクされたノードに基づくオプションで制限された双方向ブロッキングキューです。

  • ブロッキングキューは、FIFOとFILOの両方の操作モード、つまり、キューの先頭と末尾からの同時操作(挿入/削除)をサポートします。
  • ブロッキングキューはスレッドセーフです。
  • LinkedBlockingDequeを初期化するときに、その過度の拡張を防ぐために容量を設定できます。
  • 双方向ブロッキングキューは、「ワークスティーリング」(ワークスティーリング)モードで使用できます。

おすすめ

転載: blog.csdn.net/qq_27828675/article/details/115356648