Java同時メモ(14)----ブロックキュー
文書ディレクトリ
ブロックキュー
1.簡単に述べる
ブロッキングキュー(BlockingQueue)は、2つの追加操作をサポートするキューです.この2つの追加の操作は、ブロックの挿入と除去方法をサポートします.ブロックキューはスレッドプールと一緒に使用できます!
なぜブロックキューと呼ぶのですか?
挿入削除の4つの処理について説明します.
しょりモード
異常を投げ出す
特殊値を返す
ずっと塞いで
タイムアウト終了
挿入
add(e)
offer(e)
put(e)
offer(e, time, unit)
削除
remove()
poll()
take()
poll(time, unit)
検査方法
element()
peek()
使用不可
使用不可
IllegalStateException("Queuefull")
異常が放出されます.キューが空の場合、キューから要素を取得するとNoSuchElementException
異常が放出されます.boolean
タイプ2.Javaのブロックキュー
2.1 ArrayBlockingQueue(FIFO、有界)
これは境界配列です.デフォルトでは、スレッドの公平なアクセスキューは保証されません.
どうして公平な方法を使わないのですか.
公平性を保証するために、通常はスループットが低下します.
2.2 LinkedBlockingQueue(FIFO、有界)
LinkedBlockingQueue
は、チェーンテーブルによって実現される境界ブロックキューである.このキューのデフォルトおよび最大長はInteger.MAX_VALUE
です.2.3 PriorityBlockingQueue(優先キュー)
PriorityBlockingQueueは、優先度をサポートする無境界ブロックキューです.クラスインプリメンテーション
compareTo()
メソッドをカスタマイズして要素並べ替えルールを指定するか、または構造パラメータComparator
を指定して要素を並べ替えます.優先順位要素と同じ順序は保証されないことに注意してください.
2.4 DelayQueue(無境界)
キューは、
PriorityQueue
を使用して実装される.キュー内の要素はDelayedインタフェースを実装する必要があります.要素を作成するときに、キューから現在の要素を取得するにはどのくらいの時間を指定できますか.遅延期間が満了した場合にのみ、キューから要素を抽出できます.適用シーン:
2.5 SynchronousQueue(FIFO)
SynchronousQueue
は、要素を格納しないブロックキューです.各put操作はtake操作を待つ必要があります.そうしないと、要素の追加を続行できません.デフォルトでは、スレッドは非公平性ポリシーを使用してキューにアクセスします.個人的な理解:
このブロック列はCachedThreadPoolと組み合わせて使用され、このブロック列を食事の配達と見なすことができます!台所の料理を消費者に渡す.スループットが高い
2.6 LinkedBlockingDeque
LinkedBlockingDeque
は、チェーンテーブル構造からなる双方向ブロックキューである.3.実現原理
通知モードで実装
ここでは
ArrayBlockingQueue
を例にクライマックスがやってきました!!!ソース番号:/** Condition for waiting takes */
private final Condition notEmpty;
/** Condition for waiting puts */
private final Condition notFull;
public ArrayBlockingQueue(int capacity, boolean fair) {
if (capacity <= 0)
throw new IllegalArgumentException();
this.items = new Object[capacity];
lock = new ReentrantLock(fair);
notEmpty = lock.newCondition();
notFull = lock.newCondition();
}
上のコードを見ると、明らかな生産消費フォーマット+2つの待ち行列のフォーマットではないでしょうか.
次に、追加、削除操作を見てみましょう.
public void put(E e) throws InterruptedException {
checkNotNull(e);
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == items.length)
notFull.await();
enqueue(e);
// isEmpty
} finally {
lock.unlock();
}
}
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == 0)
notEmpty.await();
return dequeue();
// notFull
} finally {
lock.unlock();
}
}