BlockingQueue
ある種の要求を抑制したい場合は、容量が限られていることも役立ちます。無制限のキューを使用すると、プロデューサーはコンシューマーよりもはるかに先を行くことができます。タスクは最終的に実行されますが(それらが原因となるほど多くない限りOutOfMemoryError
)、プロデューサーは長い間あきらめている可能性があるため、労力は無駄になります。
このような状況では、キューがいっぱいであることをプロデューサーになる予定の人に通知し、失敗した場合はすぐに諦める方がよい場合があります。たとえば、プロデューサーは、あまり長く待ちたくないユーザーがいるWebリクエストであり、待機中に多くのCPUサイクルを消費しなくても、ソケットやメモリなどの限られたリソースを消費している可能性があります。 。諦めると、すでにキューに入れられているタスクがタイムリーに完了する可能性が高くなります。
私が解釈している修正された質問について、「プールにオブジェクトを保持するための良いコレクションは何ですか?」
無制限LinkedBlockingQueue
は、多くのプールに適しています。ただし、プール管理戦略によっては、aConcurrentLinkedQueue
も機能する場合があります。
プーリングアプリケーションでは、ブロッキング「プット」は適切ではありません。キューの最大サイズの制御はプールマネージャーの仕事です。プールのリソースをいつ作成または破棄するかを決定します。プールのクライアントは、プールからリソースを借りて返します。新しいオブジェクトを追加するか、以前に借用したオブジェクトをプールに戻すことは、高速で非ブロッキング操作である必要があります。したがって、制限付き容量キューはプールには適していません。
一方、プールからオブジェクトを取得する場合、ほとんどのアプリケーションは、リソースが使用可能になるまで待機します。少なくとも一時的にブロックする「取得」操作は、「ビジー待機」よりもはるかに効率的です。つまり、リソースが使用可能になるまで繰り返しポーリングします。このLinkedBlockingQueue
場合、は良い選択です。借り手は、で無期限にブロックするtake
か、でブロックする時間を制限することができますpoll
。
クライアントがまったくブロックする意思がないが、プールが空の場合にそれ自体のリソースを作成する機能がある場合は、あまり一般的ではありません。その場合、aConcurrentLinkedQueue
が適切な選択です。これは、リソース(メモリなど)を可能な限り共有するのがよい灰色の領域のようなものですが、速度はさらに重要です。最悪の場合、これはリソースの独自のインスタンスを持つすべてのスレッドに縮退します。そうすれば、スレッド間でわざわざ共有しようとしないほうが効率的だったでしょう。
これらのコレクションは両方とも、並行アプリケーションで優れたパフォーマンスと使いやすさを提供します。非並行アプリケーションの場合、これArrayList
に勝るものはありません。動的に増加するコレクションの場合でも、aの要素ごとのオーバーヘッドにより、LinkedList
いくつArrayList
かの空のスロットがあると、メモリに関して競争力を維持できます。