Javaでキューをブロックします
1.ブロッキングキューとは何ですか?
ブロッキングキュー(BlockingQueue)は、2つの追加操作をサポートするキューです。これらの2つの追加操作は次のとおりです。
キューが空の場合、要素を取得するスレッドは、キューが空でないようになるのを待ちます。
キューがいっぱいになると、要素を保存するスレッドがキューが利用可能になるのを待ちます。
ブロッキングキューは、生産者と消費者のシナリオでよく使用されます。プロデューサーは、キューに要素を追加するスレッドであり、消費者はキューから要素を取得するスレッドです。ブロッキングキューは、生産者が要素を保存するコンテナであり、消費者はコンテナからのみ要素を取得します。
2。Javaでキューをブロックします
JDKで7つのブロッキングキューが提供されています。
arrayblockingqueue
ArrayBlockingQueueは、配列を使用して実装された境界ブロッキングキューです。このキューは、ファーストインファーストアウト(FIFO)の原則に従って要素をソートします。デフォルトでは、訪問者は公平にアクセスすることを保証されていません。いわゆるかなりアクセス可能なキューは、すべてのブロックされた生産者スレッドまたは消費者スレッドを指します。キューが利用可能な場合、キューにブロックの順にアクセスできます。つまり、最初にブロックするプロデューサースレッドは、最初にキューに要素を挿入でき、最初にブロックする消費者スレッドは、最初にキューから要素を取得できます。通常、公平性を確保するために、スループットが減少します。次のコードを使用して、公正なブロッキングキューを作成できます。
arrayblockingqueue fairqueue = new arrayblockingqueue(1000、true);
そのアクセスの公平性は、ReentrantLockロックを通じて達成されます。
LinkedBlockingQueue
LinkedBlockingQueueは、リンクされたリストで実装された境界ブロッキングキューです。このキューのデフォルトと最大長はinteger.max_valueです。このキューは、ファーストインファーストの原則に従って要素をソートします。
PriorityBlockingQueue
PriorityBlockingQueueは、優先度をサポートする無制限のキューです。デフォルトでは、要素は自然な順序で配置され、要素の順序規則はコンパレータコンパレータを通じて指定することもできます。要素は昇順で配置されます。
delayqueue
Delayqueueは、要素の遅延獲得をサポートする無制限のブロッキングキューです。キューはPriorityQueueを使用して実装されます。キュー内の要素は、遅延インターフェイスを実装する必要があります。要素を作成するときは、キューから現在の要素を取得するのに時間がかかる時間を指定できます。遅延が期限切れになった場合にのみ、要素はキューから抽出できます。次のアプリケーションシナリオでDelayQueueを使用できます。
キャッシュシステムの設計:DelayQueueを使用してキャッシュ要素の有効期間を保存することができ、スレッドを使用して遅延を照会できます。要素をDelayqueueから取得できると、キャッシュの有効期間が到着したことを意味します。
スケジュールされたタスクスケジュール。 DelayQueueを使用して、日に実行されるタスクと実行時間を保存します。タスクがdelayqueueから取得されると、実行を開始します。たとえば、TimerqueueはDealequeueを使用して実装されます。
遅延インターフェイスを実装する方法
ScheduledThreadPoolexecutorのScheduledFutureTaskクラスを参照できます。このクラスは、遅延インターフェイスを実装します。最初:オブジェクトを作成するときは、時間を使用して、録画前にオブジェクトを使用できるときに記録します。コードは次のとおりです。
scheduledfuturetask(runnable r、v result、long ns、long period){super(r、result); this.time = ns; this.period = period; this.sequencenumber = sequencer.getandincrement();}次に、getDelayを使用して、現在の要素を遅延させる必要がある時間を照会します。コードは次のとおりです。
public long getdelay(timeunit unit){return unit.convert(time -now()、timeunit.nanoseconds); }コンストラクターを介して、遅延時間パラメーターnsの単位がナノ秒であることがわかります。自分で設計するときにナノ秒を使用することをお勧めします。ナノ秒がユニットとして使用されると、遅延時間がナノ秒未満になると、面倒になります。使用する場合は、時間が現在の時間よりも短い場合、GetDelayは負の数を返すことに注意してください。
最後に、時間を使用してキューの順序を指定できます。たとえば、最長の遅延時間をキューの最後に配置します。
public int compareto(他の遅延){if(other == this)return 0; if(その他のInstanceOf scheduledfutureTask){scheduledFutureTask X =(ScheduleDFUTURETASK)その他; long diff = time -x.time; if(diff <0)return -1; else if(diff> 0)return 1; else if(sequencenumber <x.sequencenumber)return -1;それ以外の場合は1; } long d =(getDelay(timeunit.nanoconds)-other.getDelay(timeunit.nanoconds)); return(d == 0)? 0:((d <0)?-1:1); }遅延ブロッキングキューを実装する方法
遅延ブロッキングキューの実装は非常に簡単です。消費者がキューから要素を取得すると、要素が遅延時間に到達しない場合、現在のスレッドがブロックされます。
長い遅延= first.getDelay(tamtil.nanoconds); if(delay <= 0){return q.poll; // blocking queue} else if(leader!= null){//リードは、blocking queue fromawait()からのメッセージを待っているスレッドを表します。 //スレッドが待機信号を入力するように} else} else {//リーダーがnullの場合、現在のスレッドをリーダーにthread = thread.currentthread(); try {leader = thisthread; // waitaitnanos()メソッドを使用して、現在のスレッドを使用して受信信号を待つか、遅延時間を待つか、待機時間を待ちます。 }}}Synchronousqueue
Synchronousqueueは、要素を保存しないブロッキングキューです。それぞれのプット操作は、テイク操作を待つ必要があります。そうしないと、要素を追加できません。 Synchronousqueueは、プロデューサースレッドによって処理されたデータを消費者スレッドに直接渡す責任を負う担当者と見なすことができます。キュー自体には要素を保存しません。これは、推移的なシナリオに非常に適しています。たとえば、あるスレッドで使用されるデータは、使用するために別のスレッドに渡されます。 Synchronousqueueのスループットはそれよりも高くなっています
LinkedBlockingQueueおよびArrayBlockingQueue。
公正なアクセスキューをサポートします。デフォルトでは、それはまだ不公平な政策メカニズムです
LinkedTransferqueue
LinkedTransferqueueは、リンクされたリスト構造で構成される無制限のブロックトランスファーキューキューです。他のブロッキングキューと比較して、LinkedTransferqueueにはより多くの試行および転送方法があります。
転送方法
消費者が現在要素を受信するのを待っている場合(消費者がTake()メソッドまたは時間制限されたPoll()メソッドを使用する場合、転送方法は、生産者が渡された要素をすぐに消費者に転送できます。受信要素を待っている消費者がいない場合、転送方法は、キューのテールノードに要素を保存し、消費者が消費するまで返品するまで待機します。
トライトランスファーメソッド
生産者によって導入された要素を消費者に直接送信できるかどうかをテストするために使用されます。受信要素を待っている消費者がいない場合、Falseが返されます。転送方法の違いは、消費者がそれを受け取るかどうかに関係なく、TryTransferメソッドがすぐに戻ることです。転送方法は、消費者が返す前に消費するまで待つ必要があります。
時間制限付きのTryTransfer(E、Long Timeout、TimeUnitユニット)メソッドの場合、生産者が消費者に直接渡す要素を渡そうとしますが、要素を消費する消費者がいない場合は、指定された時間を返す前に待ちます。タイムアウトが要素を消費していない場合、falseを返し、タイムアウト時間内に要素が消費されると、trueが返されます。
LinkedBlockingDeque
LinkedBlockingDequeは、リンクされたリスト構造で構成される双方向ブロッキングキューです。いわゆる双方向キューは、キューの両端から要素を挿入して削除できるという事実を指します。両端のキューには操作キューへの追加のエントリがあるため、複数のスレッドが同時にキューに参加すると、競争は半分に減少します。他のブロッキングキューと比較して、LinkedBlockingDequeには、AddFirst、AddLast、Offerfirst、Offerlast、Peekfirst、Peeklast、その他の方法が増えています。この方法は、最初の単語で終わり、二重端キューの最初の要素の挿入、取得、または削除を示します。最後の単語で終わるメソッド。二重端キューの最後の要素が挿入、取得、または削除されたことを示します。さらに、挿入方法ADDはAddLastと同等であり、除去方法の削除は削除と同等です。ただし、TakeメソッドはTakeFirstと同等です。 JDKのバグであるかどうかはわかりませんが、使用時に最初と最後の接尾辞でメソッドを使用することは明確です。キューの容量は、LinkedBlockingDequeを初期化するときに初期化して、再登録されたときに腫れを防ぐことができます。さらに、双方向ブロッキングキューは、「作業盗難」モードで使用できます。
読んでくれてありがとう、私はそれがあなたを助けることができることを願っています。このサイトへのご支援ありがとうございます!