1.ブロッキングキューとは何ですか?
キューは、2つの基本操作を備えたデータ構造です。キューの最後に要素を追加し、キューのヘッドから要素を削除することです。ブロッキングチームと通常のキューの違いは、通常のキューが現在のスレッドをブロックしないことです。同様の消費者プロデューサーモデルに直面する場合、追加の同期戦略とスレッド間ウェイクアップ戦略を実装する必要があります。ブロッキングキューを使用すると、現在のスレッドがブロックされます。キューが空の場合、キューから要素を取得する操作がブロックされます。キューがいっぱいの場合、キューに要素を追加する操作もブロックされます。
2。メインブロッキングキューとその方法
java.util.concurrentパッケージは、主に次のように、いくつかのメインブロッキングキューを提供します。
1)ArrayBlockingQueue:配列の実装に基づくブロッキングキュー。 ArrayBlockingQueueオブジェクトを作成する場合、その容量を指定する必要があります。アクセスポリシー用に指定することもできます。デフォルトでは、それは公平ではありません。つまり、最長の待ち時間のスレッドが最初にキューにアクセスできることを保証するものではありません。
2)LinkedBlockingQueue:リンクリストに基づくブロッキングキュー。 linkedblockingQueueオブジェクトを作成するときに容量のサイズが指定されていない場合、デフォルトのサイズはinteger.max_valueです。
3)上記の2つのキューはファーストインファーストキューですが、PriorityBlockingQueueはそうではありません。要素の優先度に応じて要素を優先順序で並べ替えます。各要素dequeueは、最優先要素です。このブロッキングキューは、固定されていないブロッキングキューであることに注意してください。つまり、容量に上限はありません(ソースコードを通じて、コンテナでいっぱいの信号フラグがないことを知ることができます)。最初の2つのタイプは、境界のあるキューです。
4)DelayQueue:PriorityQueueに基づいて、遅延ブロッキングキュー。遅延の要素は、指定された遅延時間が到達した場合にのみ、キューから要素を取得できます。 Delayqueueは無制限のキューでもあるため、キューにデータを挿入する操作(プロデューサー)はブロックされることはなく、データを取得する操作(消費者)のみがブロックされます。
ブロッキングキューには、非ブロッキングキューのほとんどの方法が含まれており、他のいくつかの非常に有用な方法を提供します。
PUTメソッドは、要素をキューのテールに保存するために使用され、キューがいっぱいの場合は待ってください。
テイクメソッドは、キューから要素を取得するために使用され、キューが空の場合は待ってください。
オファーメソッドは、キューのテールに要素を保存するために使用されます。キューがいっぱいの場合、特定の時間を待ちます。期間に達すると、挿入が成功していない場合、虚偽を返します。それ以外の場合は、trueを返します。
投票方法は、最初のキューから要素を取得するために使用されます。キューが空の場合、特定の時間を待ちます。期間に達すると、それが取得された場合、それはnullを返します。それ以外の場合、取得した要素を返します。
これがコードです:
Import java.util.concurrent.arrayblockingqueue;/** * @author著者:xu jiane-mail:[email protected] * @version reaced:2016年3月20日12:52:53 java.util.concurrent.blockingqueue <string> blockingqueue = new arrayblockingqueue <>(5); for(int i = 0; i <10; i ++){//指定された要素をこのキューブロッキングqueue.put( "add element"+i); System.out.println( "ブロッキングキューに要素を追加しました:" + i); } system.out.println( "プログラムは今回終了し、終了します----"); }}
5つの要素を追加した後、制限ブロッキングキューの数が5の場合、プロセスはキューの外側でブロックされ、待機し、この時点ではプログラムが終了しません。
キューがいっぱいになったら、ヘッダー要素を削除し、ブロッキングキューに要素を追加し続けることができます。コードは次のとおりです。
public class blockingQueue {public static void main(string [] args)arturtedexception {java.util.concurrent.blockingqueue <string> blockingqueue = new arrayblockingqueue <>(5); for(int i = 0; i <10; i ++){//指定された要素をこのキューブロッキングqueue.put( "add element"+i); System.out.println( "ブロッキングキューに要素を追加しました:" + i); if(i> = 4)system.out.println( "ヘッダー要素を削除" +blockingqueue.take()); } system.out.println( "プログラムは今回終了し、終了します----"); }実行結果は次のとおりです。
3。キューをブロックするという実装の原則<BR />
まず、ArrayBlockingQueueクラスのメンバー変数を見てみましょう。
public class arrayblockingqueue <e> extends abstractqueue <e> BlockingQueue <e>、java.io.serializable { / **基礎となるストレージ構造配列* / finalオブジェクト[]アイテム。 / ** Team Head Element Subscript*/ int takeIndex; / ** Team Tail Element Subscript*/ int putindex; / **キュー要素の総数*/ intカウント。 / ** REENTRANTLOCK*/ FINAL REENTRANTLOCK LOCK; / ** notempty wait条件*/プライベート最終条件Notempty; / **著名な待機状態*/プライベート最終条件著名な; /** *現在アクティブなイテレーターの共有状態、またはnullがある場合はnullがないことが知られていないことがわかっています。キュー操作が *イテレーター状態を更新できるようにします。 */一時的なITRS ITRS = null;ご覧のとおり、要素を保存するために使用されるArrayBlockingQueueは実際には配列です。
ArrayBlockingQueueの2つの重要な方法の実装、put()とtake()の実装を見てみましょう。
public void put(e e)throws arturtedexception {// eが空であるかどうかを最初に確認します(e); // Lock final resentrantlock lock = this.lockを取得します。 lock.lockinterrumdibly(); {//キューがいっぱいになったら、状態を入力して、while(count == items.length)notfull.await(); //キューが満たされていない、キュー操作enqueue(e)を実行します。 }最後に{// lock.unlock(); }}特定の参加操作を見てみましょう。
private void enqueue(e x){final object [] items = this.items; // enterminationアイテム[putindex] = x; if(++ putindex == items.length)putindex = 0; //キューの総数+1カウント++; //ノートメント条件の待機セットでランダムにスレッドを選択して、ブロック状態NOTEMPTY.SIGNAL()をブロックして解除します。 } Take()メソッドのソースコードは次のとおりです。
public e take()throws arturnedexception {// lock final reentrantlock lock = this.lock; lock.lockinterrumdibly(); try {//キューは空です(count == 0)//スレッドは、notempty条件待機セットNotempty.await(); //空でない、キューリターンdequeue()を終了します。 }最後に{// lock.unlock(); }} 4。ブロッキングキューの適用:消費者プロデューサーモデルの実装
/** * @Author著者:Xu Jiane-Mail:[email protected] * @version作成時間:2016年3月20日午後2:21:55 PM *クラス説明:消費者プロデューサーモードは、blocking Queue */public class test {private int queuesize = 10; private arrayblockingqueue <integer> queue = new arrayblockingqueue <integer>(queuesize); public static void main(string [] args){test test = new test();プロデューサープロデューサー= test.new producer(); Consumer Consumer = test.new Consumer(); producer.start(); Consumer.start(); } class Consumer extends thread {@override public void run(){consumption(); } private void consumption(){while(true){try {queue.take(); system.out.println( "キューから要素を取ります。キューは" + queue.size() + "elements"); } catch(arturnedexception e){e.printstacktrace(); }}}} classプロデューサーはスレッドを拡張します{@Override public void run(){produce(); } private void produce(){while(true){try {queue.put(1); system.out.println( "要素をキューに挿入し、キュー内の残りのスペースを挿入します。 } catch(arturnedexception e){e.printstacktrace(); }}}}}}
上記はこの記事に関するものです。すべての人の学習に役立つことを願っています。