ほとんどの場合、ArrayBlockingQueue
はLinkedBlockingQueue
よりもパフォーマンスが優れていると思います。ただし、これは、配列に常に十分なスペースがある場合に当てはまります...いっぱいになると、データをキューにプッシュしようとしているスレッドをブロックするため、十分に機能するかどうかはあまり予測できません。 。
だから、私の質問は:BlockingQueue
の中間的な実装はありますか?たとえば、ArrayListBlockingQueue
またはBucketListBlockingQueue
?配列のリストのようなもので、キューの容量を動的に増やすことができますが、配列を使用して最終的にデータを格納することで合理的なメリットが得られますか?
1。 LinkedBlockingQueue(LinkedList実装ですが、LinkedListのJDK実装ではありません静的内部クラスNodeを使用して要素間のリンクを維持します)
Constructor for LinkedBlockingQueue
public LinkedBlockingQueue(int capacity)
{
if (capacity < = 0) throw new IllegalArgumentException();
this.capacity = capacity;
last = head = new Node< E >(null); // Maintains a underlying linkedlist. ( Use when size is not known )
}
リンクを維持するために使用されるノードクラス
static class Node<E> {
E item;
Node<E> next;
Node(E x) { item = x; }
}
2。 ArrayBlockingQueue(配列の実装)
ArrayBlockingQueueのコンストラクター
public ArrayBlockingQueue(int capacity, boolean fair)
{
if (capacity < = 0)
throw new IllegalArgumentException();
this.items = new Object[capacity]; // Maintains a underlying array
lock = new ReentrantLock(fair);
notEmpty = lock.newCondition();
notFull = lock.newCondition();
}
ArrayBlockingQueueとLinkedBlockingQueueのIMHOの最大の違いは、基礎となるデータ構造Arrayと他のlinkedListを持つコンストラクターから明らかです。
ArrayBlockingQueueは シングルロックダブル条件アルゴリズム を使用し、LinkedBlockingQueueは「2ロックキュー」アルゴリズムの変形であり、2つのロック2つの条件(takeLock、putLock)があります。
これまで、これら2つの実装の比較を行いました。元の質問に戻って、同様の質問が concurrencyメーリングリスト で行われました。このダグのLeaは、 Dawid Kurzyniecによって提供される実装
私の2セント:
まず、ここで重要なのは、ここでの違いはあまり気にしないということです。プレーンなLinkedBlockingQueueを使用している場合でも、マイクロ秒レベルのシステムを提供している場合はパフォーマンスが十分に優れているからです。したがって、ここでのパフォーマンスの違いはそれほど大きくありません。
ミッションクリティカルな高性能システムを作成していて、キューを使用してスレッド間でメッセージを渡す場合は、[キューサイズ] = [最大許容遅延] * [最大メッセージレート]で必要なキューサイズをいつでも見積もることができます。そのような容量を超えて成長する可能性があるものはすべて、消費者の遅い問題に苦しんでいることを意味します。ミッションクリティカルなアプリケーションでは、このような遅延はシステムが誤動作していることを意味します。システムが正しく実行されていることを確認するには、手動プロセスが必要になる場合があります。
システムがミッションクリティカルでない場合は、一部のコンシューマが利用可能になるまでパブリッシャを一時停止(ブロック)できます。