前回の記事では、Java並行プログラミングのツールであるBlockingQueueインターフェース、ArrayBlockingQueue、DelayQueueを紹介しました。
LinkedBlockingQueueキューは、BlockingQueueインターフェイスの実装クラスであるため、BlockingQueueインターフェイスのすべての機能を備えています。LinkedBlockingQueueは、先入れ先出し(FIFO)先入れ先出し方式で要素をキューに入れます。LinkeBlockingQueueは、2つのコンストラクターを提供します。1つのコンストラクターは固定数のキューでキューを構築し、もう1つのパラメーターなしのコンストラクターはキュー容量でキューを構築しますInteger.MAX_VALUE
。
public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}
public LinkedBlockingQueue(int capacity) {
if (capacity <= 0) throw new IllegalArgumentException();
this.capacity = capacity;
last = head = new Node<E>(null);
}
ArrayBlockingQueueとLinkedBlockingQueueの比較
ArrayBlockingQueueとLinkedBlockingQueueはどちらもBlockingQueueインターフェースを実装しているため、使用法は一貫しています。以下では使用法を紹介しませんが、2つのパフォーマンスと基盤となるデータ構造の実装の観点から進めます。
ArrayBlockingQueueは、1つのロックのみを使用してデータを挿入および削除し、読み取り操作と書き込み操作を並行して実行することはできません。したがって、同時実行性の高いシナリオでの実行効率は、LinkedBlockingQueueよりも遅くなります。
- LinkedBlockingQueueは、「2ロックキュー」アルゴリズムバリアントであるダブルロック(ReentrantLock)を使用します。takeLock、putLock、並列読み取りと書き込みを可能にし、remove(e)とイテレーターは2つのロックを取得する必要があります。これにより、スレッドがロックを取得できないためにスレッドがWAITING状態になる可能性を減らすことができ、それによってスレッドの同時実行の効率が向上します。
- ArrayBlockingQueueの基礎となるコードは、配列を使用して実装されます。作成時に、キューの容量を指定してストレージスペースを割り当てる必要があります。LinkedBlockingQueueはリンクリストデータ構造を使用して実装され、リンクリストノードのストレージスペース割り当ては動的です。新しい要素オブジェクトは、割り当てスペース、要素オブジェクトがキューから取り出された後のストレージスペースGCのためにキューに追加され、キューの最大容量は初期化中に指定されます。ただし、リンクリストデータ構造の使用は、LinkedBlockingQueueの長所と短所の両方です。同時実行性の高いシナリオでは、動的なスペース割り当てのために、JavaJVMを頻繁にガベージコレクションする必要があります。
一般的に、並行シナリオでは、LinkedBlockingQueueのスループットはArrayBlockingQueueのスループットよりも優れています。ただし、Javaで高性能キューを実装するための最初の選択肢は、JDKに含まれていないディスラプターです。Javaプログラマーがよく知っているLog4j2の基本的なパフォーマンスは、logbackやlog4jと比較して大幅に改善されています。その理由は、ディスラプターの高性能キューによって実装された非同期ログが使用されるためです。
私のブログをフォローすることを歓迎します、多くのブティックコレクションがあります
- この記事は、出典を示して複製されています(接続を添付する必要があり、テキストのみを複製することはできません):レターブラザーのブログ。
あなたがそれがあなたに役立つと思うなら、私のためにそれを好きにして共有してください!あなたのサポートは私の尽きることのない創造的な動機です!。また、最近、以下のような高品質なコンテンツを出力しておりますので、よろしくお願いいたします。