web-dev-qa-db-ja.com

Java:ArrayBlockingQueueとLinkedBlockingQueue

ほとんどの場合、ArrayBlockingQueueLinkedBlockingQueueよりもパフォーマンスが優れていると思います。ただし、これは、配列に常に十分なスペースがある場合に当てはまります...いっぱいになると、データをキューにプッシュしようとしているスレッドをブロックするため、十分に機能するかどうかはあまり予測できません。 。

だから、私の質問は:BlockingQueueの中間的な実装はありますか?たとえば、ArrayListBlockingQueueまたはBucketListBlockingQueue?配列のリストのようなもので、キューの容量を動的に増やすことができますが、配列を使用して最終的にデータを格納することで合理的なメリットが得られますか?

17
Eduardo Bezerra

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によって提供される実装

14
Vipin

私の2セント:

まず、ここで重要なのは、ここでの違いはあまり気にしないということです。プレーンなLinkedBlockingQueueを使用している場合でも、マイクロ秒レベルのシステムを提供している場合はパフォーマンスが十分に優れているからです。したがって、ここでのパフォーマンスの違いはそれほど大きくありません。

ミッションクリティカルな高性能システムを作成していて、キューを使用してスレッド間でメッセージを渡す場合は、[キューサイズ] = [最大許容遅延] * [最大メッセージレート]で必要なキューサイズをいつでも見積もることができます。そのような容量を超えて成長する可能性があるものはすべて、消費者の遅い問題に苦しんでいることを意味します。ミッションクリティカルなアプリケーションでは、このような遅延はシステムが誤動作していることを意味します。システムが正しく実行されていることを確認するには、手動プロセスが必要になる場合があります。

システムがミッションクリティカルでない場合は、一部のコンシューマが利用可能になるまでパブリッシャを一時停止(ブロック)できます。

7
Alex Suo