1. ホーム
  2. java

[解決済み] Javaでどの並列Queue実装を使うべきですか?

2022-05-11 18:38:02

質問

JavaDocsより。

  • A ConcurrentLinkedQueue は、多くのスレッドが共通のコレクションへのアクセスを共有する場合に適切な選択です。このキューは null 要素を許可しません。
  • ArrayBlockingQueue は古典的なバッファで、固定サイズの配列がプロデューサによって挿入され、コンシューマによって取り出された要素を保持します。このクラスは、待機中のプロデューサーとコンシューマースレッドを順番に並べるためのオプションの公平性ポリシーをサポートします。
  • LinkedBlockingQueue は、一般に配列ベースのキューよりも高いスループットを持ちますが、ほとんどの同時実行アプリケーションでは予測可能なパフォーマンスは低くなります。

1 つは、キューが 1 つのコンシューマで多くのプロデューサ (それを使用するスレッド) をサポートする必要があり、もう 1 つはその逆です。

私は、どちらの実装を使用すべきか理解していません。どなたか、どのような違いがあるのかを説明していただけないでしょうか。

また、「オプションの公平性ポリシー」の中で ArrayBlockingQueue ?

どのように解決するのですか?

基本的に両者の違いは、パフォーマンス特性とブロック動作です。

最も簡単なものから順に ArrayBlockingQueue は固定サイズのキューです。そのため、サイズを 10 に設定し、11 番目の要素を挿入しようとすると、他のスレッドが要素を削除するまで insert 文はブロックされます。公平性の問題は、複数のスレッドが同時に(言い換えればQueueがブロックされていた期間に)挿入と削除を試みた場合にどうなるかということである。公平性アルゴリズムは、最初に要求したスレッドが最初に取得するスレッドであることを保証します。そうしないと、あるスレッドが他のスレッドよりも長く待つことになり、予測不可能な動作が発生します (あるスレッドが数秒かかるだけで、後から開始した他のスレッドが先に処理されてしまうこともあります)。トレードオフは、公平性を管理するためにオーバーヘッドがかかり、スループットが遅くなることです。

との最も重要な違いは LinkedBlockingQueueConcurrentLinkedQueue から要素を要求した場合、その要素は LinkedBlockingQueue に要素を要求し、キューが空であれば、スレッドはそこに何かがあるまで 待つことになります。A ConcurrentLinkedQueue は空のキューの挙動ですぐに戻ってきます。

どちらがいいかは、ブロッキングが必要かどうかによります。多くのプロデューサーと一人のコンシューマーがいる場合、そのように聞こえます。一方、多くのコンシューマと1人のプロデューサがいる場合、ブロッキング動作は必要なく、コンシューマにキューが空かどうかをチェックさせ、空なら移動させるだけでよいかもしれません。