29

私は私の質問を

Simple Queue Implementations の代わりに BlockingQueue Implementations をどこで使用する必要がありますか?

最後の要素にアクセスする時間など、さまざまな速度、同時実行性、またはその他のプロパティなどの側面を考慮して、Queue 実装に対する BlockingQueue の利点/欠点は何ですか。

私は両方の種類のキューを使用しました。Blocking Queue は通常、並行アプリケーションで使用されることを知っています。ByteBuffer オブジェクトのプレースホルダーが必要な単純な ByteBuffer プールを作成していました。最速でスレッドセーフなキューの実装が必要でした。要素への一定のアクセス時間を持つ ArrayList のような List 実装もあります。

BlockingQueue と Queue と List の実装の長所と短所について誰でも議論できますか?

現在、これらの ByteBuffer オブジェクトを保持するために ArrayList を使用しています。

これらのオブジェクトを保持するためにどのデータ構造を使用すればよいでしょうか?

4

3 に答える 3

39

BlockingQueueある種の要求を抑制したい場合は、容量が限られていることも役立ちます。無制限のキューを使用すると、プロデューサーはコンシューマーよりもはるかに先を行くことができます。タスクは最終的に実行されますが(それらが原因となるほど多くない限りOutOfMemoryError)、プロデューサーは長い間あきらめている可能性があるため、労力は無駄になります。

このような状況では、キューがいっぱいであることをプロデューサーになる予定の人に通知し、失敗した場合はすぐに諦める方がよい場合があります。たとえば、プロデューサーは、あまり長く待ちたくないユーザーがいるWebリクエストであり、待機中に多くのCPUサイクルを消費しなくても、ソケットやメモリなどの限られたリソースを消費している可能性があります。 。諦めると、すでにキューに入れられているタスクがタイムリーに完了する可能性が高くなります。


私が解釈している修正された質問について、「プールにオブジェクトを保持するための良いコレクションは何ですか?」

無制限LinkedBlockingQueueは、多くのプールに適しています。ただし、プール管理戦略によっては、aConcurrentLinkedQueueも機能する場合があります。

プーリングアプリケーションでは、ブロッキング「プット」は適切ではありません。キューの最大サイズの制御はプールマネージャーの仕事です。プールのリソースをいつ作成または破棄するかを決定します。プールのクライアントは、プールからリソースを借りて返します。新しいオブジェクトを追加するか、以前に借用したオブジェクトをプールに戻すことは、高速で非ブロッキング操作である必要があります。したがって、制限付き容量キューはプールには適していません。

一方、プールからオブジェクトを取得する場合、ほとんどのアプリケーションは、リソースが使用可能になるまで待機します。少なくとも一時的にブロックする「取得」操作は、「ビジー待機」よりもはるかに効率的です。つまり、リソースが使用可能になるまで繰り返しポーリングします。このLinkedBlockingQueue場合、は良い選択です。借り手は、で無期限にブロックするtakeか、でブロックする時間を制限することができますpoll

クライアントがまったくブロックする意思がないが、プールが空の場合にそれ自体のリソースを作成する機能がある場合は、あまり一般的ではありません。その場合、aConcurrentLinkedQueueが適切な選択です。これは、リソース(メモリなど)を可能な限り共有するのがよい灰色の領域のようなものですが、速度はさらに重要です。最悪の場合、これはリソースの独自のインスタンスを持つすべてのスレッドに縮退します。そうすれば、スレッド間でわざわざ共有しようとしないほうが効率的だったでしょう。

これらのコレクションは両方とも、並行アプリケーションで優れたパフォーマンスと使いやすさを提供します。非並行アプリケーションの場合、これArrayListに勝るものはありません。動的に増加するコレクションの場合でも、aの要素ごとのオーバーヘッドにより、LinkedListいくつArrayListかの空のスロットがあると、メモリに関して競争力を維持できます。

于 2008-12-11T06:20:37.593 に答える
4

BlockingQueueマルチスレッドの状況で見られます。たとえば、コンストラクターを使用して作成する場合はBlockingQueue、作成するパラメーターとして a を渡す必要があります。ThreadPoolExecutorエグゼキューターに渡すキューのタイプに応じて、異なる動作をする可能性があります。

于 2008-12-11T04:40:50.713 に答える