LinkedBlockingQueue
よりArrayBlockingQueue
を優先する場合
LinkedBlockingQueue
とArrayBlockingQueue
の間で使用するデータ構造は次の場合です。
同様の質問がありますが、どちらが優先されるべきかという事実を強調していませんか?
リンク:
Boris the Spiderは、すでにArrayBlockingQueue
とLinkedBlockingQueue
の最も顕著な違いを概説しています-前者は常に境界があり、後者は境界がありません。
したがって、無制限のブロッキングキューが必要な場合、LinkedBlockingQueue
として使用されるLinkedTransferQueue
またはBlockingQueue
がJava.util.concurrent
ツールボックスからの最善策です。
しかし、制限されたブロッキングキューが必要だとしましょう。最終的には、実際のワークロードのシミュレーションを使用した広範な実験に基づいて実装を選択する必要があります。それにも関わらず、ここでは、選択や実験結果の解釈に役立ついくつかの注意事項を示します。
ArrayBlockingQueue
は、構成可能な(オン/オフ)スケジューリング公平性ポリシーを使用して作成できます。これは、公平性が必要な場合、または生産者/消費者の飢starを回避したい場合に最適ですが、スループットが犠牲になります。ArrayBlockingQueue
はそのバッキング配列を事前に割り当てます。そのため、使用中にノードを割り当てませんが、メモリのかなりの部分になる可能性のあるものをすぐに使用します。ArrayBlockingQueue
はパフォーマンスのばらつきが少ないはずです。全体的に可動部分が少なく、よりシンプルで洗練されていないシングルロックアルゴリズムを使用し、使用中にノードを作成せず、キャッシュ動作はかなり一貫している必要があります。LinkedBlockingQueue
は、ヘッドとテールに別々のロックを使用するため、スループットが向上するはずです。LinkedBlockingQueue
はノードを事前に割り当てません。これは、メモリフットプリントがサイズとほぼ一致することを意味しますが、ノードの割り当てと解放のための作業が発生することも意味します。LinkedBlockingQueue
はおそらくキャッシュの動作が悪くなり、それ自体のパフォーマンスに影響する可能性がありますが、誤った共有により他のコンポーネントのパフォーマンスにも影響する可能性があります。ユースケースとパフォーマンスをどの程度重視するかに応じて、Java.util.concurrent
の外側を見て、 Disruptor (非常に高速ですが、ある程度特殊な有界ノンブロッキングを検討することもできます。リングバッファー)または JCTools (プロデューサーとコンシューマーの数に応じて保証が異なるさまざまな境界付きまたは境界なしのキュー)。
JavaDoc for ArrayBlockingQueue
から
bounded配列に裏打ちされたブロッキングキュー。
重点鉱山
LinkedBlockingQueue
のJavaDoc から:
リンクされたノードに基づくoptionally-boundedブロッキングキュー。
重点鉱山
したがって、boundedキューが必要な場合は、unboundedキューLinkedBlockingQueue
を使用する必要があります。
boundedキューの場合、より良い結果を得るためにベンチマークする必要があります。