この記事では、主に並行性に関連するコレクションについて説明しています。通常のコレクションについては、[Javaコレクションの概要]を参照してください
1。ブロックキューとは何ですか
ブロッキングキューはブロッキングキューです。ブロッキングという言葉から、ブロッキングキューへのアクセスが場合によっては閉塞を引き起こす可能性があることがわかります。 2つの主要なブロックされたケースがあります。
1.キューがいっぱいになると、それはenquedされます。
2。キューが空の場合、キューから外れます。
したがって、スレッドがすでに完全なキューをキューにしようとすると、別のスレッドがキュー操作を行わない限り、ブロックされます。同様に、スレッドが空のキューをキューにしようとすると、別のスレッドにキュー操作がない限り、ブロックされます。
Javaでは、BlockingQueueインターフェイスはjava.util.concurrentパッケージ(Java 5バージョンで提供)にあります。上記で紹介したブロッキングキューの特性から、ブロッキングキューがスレッドセーフであることがわかります。
2。ブロックキューの使用方法
ブロッキングキューは、主にプロデューサー/消費者シナリオで使用されます。次の写真は、スレッドの生産とスレッド消費シナリオを示しています。
生産の原因となるスレッドは、新しいオブジェクトを継続的に作成し、このキューの上限に達するまでブロッキングキューに挿入します。キューが上限に達すると、消費されるスレッドがキューを消費するまで、生産スレッドがブロックされます。同様に、消費の責任あるスレッドは、キューが空になるまでキューからオブジェクトを常に消費します。キューが空の場合、キュー内の新しいオブジェクトが挿入されない限り、消費スレッドがブロックされます。
3。ブロックキューインターフェイスのメソッド
それぞれinsert 、 remove 、およびexamine実行するためのキューをブロックするための4つのセットの方法があります。メソッドの各セットに対応する操作をすぐに実行できない場合、異なる反応があります。次の表には、これらのメソッドに分類された方法を示します。
| - | 例外をスローします | 特別価値 | ブロック | 時があります |
|---|---|---|---|---|
| 入れる | 追加(o) | オファー(o) | put(o) | オファー(O、タイムアウト、タイムニット) |
| 取り除く | 削除(o) | poll() | 取る() | 世論調査(タイムアウト、タイムニット) |
| 診る | 要素() | ピーク() |
これらの4つのメソッドセットの対応する特性は、次のとおりです。
1。スローセックス:操作をすぐに実行できない場合、例外がスローされます。
2。SpecialValue:操作をすぐに実行できない場合、特別な値が返されます。通常は真または偽
3。ブロック:操作をすぐに実行できない場合、操作はブロックされます
4。タイムアウト:操作をすぐに実行できない場合、指定された時間に操作がブロックされます。指定された時間が実行されない場合、特別な値が返されます。これは通常真または偽です。
nullをブロックキューに挿入できないことに注意してください。そうしないと、 NullPointerExceptionが報告されます。
4。BlockingQueueの実装クラス
BlockingQueueは、 java.util.concurrentパッケージの単なるインターフェイスです。具体的に使用する場合、実装クラスを使用します。もちろん、これらの実装クラスはjava.util.concurrentパッケージにもあります。 Java 6では、BlockingQueueの実装クラスは主に次のとおりです。
1。ArrayBlockingQueue
2。遅延
3。LinkedBlockingQueue
4。PriorityBlockingQueue
5。Synchronousqueue
以下に、これらの実装クラスを個別に紹介します。
4.1 ArrayBlockingQueue
ArrayBlockingQueueは境界のあるブロッキングキューであり、その内部実装は配列です。境界の意味は、容量が制限されていることを意味します。容量が初期化されたときに容量のサイズを指定する必要があり、容量のサイズを指定したら変更できません。
ArrayBlockingQueueは、ファーストインファーストアウト方法でデータを保存します。新しく挿入されたオブジェクトは尾で、新しく移動したオブジェクトはヘッドです。以下は、ArrayBlockingQueueを初期化して使用する例です。
blockingqueue queue = new arrayblockingqueue(1024); queue.put( "1"); object object = queue.take();
4.2遅延
Delayqueueブロックは、その内部要素です。 delayqueueの要素は、 java.util.concurrent.Delayedインターフェイスを実装する必要があります。このインターフェイスの定義は非常に簡単です:
パブリックインターフェイスの遅延拡張<delayed> {long getDelay(TimeUnitユニット);} getDelay()メソッドの返品値は、キュー要素がリリースされる前の保持時間です。 0または负值が返された場合、要素が期限切れになり、リリースする必要があることを意味します。現時点では、DelayedQueueはtake()メソッドを通じてこのオブジェクトをリリースします。
上記の遅延インターフェイス定義からわかるように、 Comparableインターフェイスも継承します。これは、Delayedqueueの要素をソートする必要があるためです。一般的に言えば、要素の有効期限を優先して並べ替えます。
例1:オブジェクトの有効期限を指定します
最初に、遅延インターフェイスを実装する必要がある要素を定義します
パブリッククラスの遅延採用は、遅延した{プライベートロングの期限切れ。プライベートの長い遅延;プライベート文字列名; DelayedElement(String ElementName、Long Delay){これ。 name = elementName;これ。遅延=遅延;期限切れ=(delay +System。CurrentTimeMillis()); } @Override public int compareto(delayed o){delayedelement cached =(delayedelement)o; cached.getExpired()> expired?1:-1を返します。 } @Override public long getDelay(timeUnit unit){return(expired -system。currentTimemillis()); } @Override public String toString(){return "delayedElement [delay =" + delay + "、name =" + name + "]"; } public long getExpired(){return expired; }}この要素の有効期限を3秒に設定します
public class delayqueueexample {public static void main(string [] args)throws arturnedexception {delayqueue <delayedelement> queue = new Delayqueue <>(); Deledelement ELE = new DelayedElement( "Cache 3秒"、3000); queue.put(ele);システム。 out.println(queue.take()); }}この主な関数を実行すると、このオブジェクトを印刷する前に3秒待つ必要があることがわかります。
実際、タイミングの閉鎖接続、キャッシュオブジェクト、タイムアウト処理、その他のシナリオなど、Delayqueueには多くのアプリケーションシナリオがあります。学生の試験を例として受けましょう。
例2:試験のすべての学生を遅延として扱います。質問を終えた人は、最初にそれらをリリースします
まず、学生オブジェクトを構築します
パブリッククラスの学生は、実行可能、遅延{プライベート文字列名; //プライベートロングコストタイムの名前; //テスト質問の時間プライベート長い終了時間; name = name;これ。 COSTTIME = COSTTIME; finedtime = costtime + system。 currenttimemillis(); } @Override public void run(){system。 out.println(name + "Paper、time" + costtime /1000); } @Override public long getDelay(timeUnit unit){return(finentTime -system。CurrentTimeMillis()); } @Override public int compareto(delayed o){desute other =(desute)o; return costtime> =その他。コストタイム?1:-1; }}次に、教師のオブジェクトを構築して、生徒に試験を受けます
パブリッククラス教師{Static final int student_size = 30; public static void main(string [] args)throws arturtedexception {random r = new Random(); //すべての学生を遅延キューdelayqueue <Student>学生= new DelayQueue <Student>(); //スレッドプールを構築して、生徒に「宿題をする」executorservice exec = executors.newfixedthreadpool(susteant_size); for(int i = 0; i <student_size; i ++){//学生の名前とtimeを初期化してテストsustent.put(new Student( "desute" +(i + 1)、3000 + r.nextint(10000))); } //テストを開始しますwhile(!sustent..isempty()){exec.execute(sustent.take()); } exec.shutdown(); }}実行中の結果を見てみましょう。
学生2論文を提出する3
学生1ペーパーでの手渡し、5を取る
学生5論文を提出する7
学生4紙を提出して8を取ってください
学生3論文を提出する11
実行された結果を通じて、指定された開始時間が到着した後( getDelay()メソッドに応じて) 、各生徒が「論文を提出」することがわかります。
ソースコードを見ると、Delayqueueの内部実装がPriorityQueueとロックを使用していることがわかります。
4.3 LinkedBlockingQueue
LinkedBlockingQueueの構成ブロッキングキューサイズはオプションです。初期化時にサイズを指定すると、境界が付けられ、指定されていない場合は境界が付けられます。無限と言われていますが、実際には、デフォルトのサイズはInteger.MAX_VALUE容量です。その内部実装はリンクされたリストです。
ArrayBlockingQueueと同様に、LinkedBlockingQueueはデータもファーストアウトでデータを保存します。新しく挿入されたオブジェクトは尾で、新しく移動したオブジェクトはヘッドです。以下は、LinkedBlockingQueueの初期化と作成の例です。
blockingqueue <string> unbounded = new linkedblockingqueue <string>(); blockingqueue <string>
4.4 PriorityBlockingQueue
PriorityBlockingQueueは境界のないキューであり、そのソートルールはjava.util.PriorityQueueと同じです。 nullオブジェクトをpriorityblockingqueueに挿入できることに注意する必要があります。
PriorityBlockingQueueに挿入されたすべてのオブジェクトは、 java.lang.Comparableのないインターフェイスを実装する必要があり、キューの優先順位ソートルールは、このインターフェイスの実装に従って定義されます。
さらに、PriorityBlockingQueueからイテレーターを取得できますが、このイテレーターは優先順序でイテレーションを保証しません。
説明する例を示しましょう。最初に、匹敵するインターフェイスを実装する必要があるオブジェクトタイプを定義します。
パブリッククラスの優先順位の実装<<priorityelement> {private int priority; // Define priority priorityelement(int priority){//優先度this.priority = priority;}@overridepublic int compareo(priorityelement o){//優先サイズによるソート>優先順位> = o.getPriority( 1:-1;} public int getPriority(){return priority;} public void setpriority(int priority){this.priority = priority;}@overridepublic string toString(){return "priority =" + priory + "];}}}}次に、キューの優先度をランダムに設定します
public class priorityblockingQueeExample {public static void main(string [] args)throws arturnedexception {priorityblockingqueue <priorityelement> queue = new priorityblockingqueue <>(); for(int i = 0; i <5; i ++){random = new Random(); PriorityElement ELE = new PriorityElement(random.nextint(10)); queue.put(ele); } while(!queue.isempty()){system.out.println(queue.take()); }}}実行中の結果をチェックしてください:
PriorityElement [Priority = 3]
PriorityElement [Priority = 4]
PriorityElement [Priority = 5]
PriorityElement [Priority = 8]
PriorityElement [Priority = 9]
4.5 synchronousqueue
Synchronousqueueキュー内で1つの要素のみが許可されます。スレッドが要素を挿入すると、要素が別のスレッドによって消費されない限り、ブロックされます。
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。