ホームページ  >  記事  >  Java  >  Java キューの使用法の概要

Java キューの使用法の概要

高洛峰
高洛峰オリジナル
2016-12-01 13:17:491120ブラウズ

キューの概要

Java キューの使用法の概要

図に示すように、JDK は同時キュー用に 2 セットの実装を提供します。1 つは ConcurrentLinkedQueue で表される高性能のノンブロッキング キューで、もう 1 つは BlockingQueue インターフェイスで表されるブロッキング キューです。両方とも Queue から継承します。ブロッキング アルゴリズムを使用するキューは、1 つのロック (エンキューとデキューに同じロックが使用される) または 2 つのロック (エンキューとデキューに異なるロックが使用される) を使用して実装できます。非ブロッキング実装は、ループを使用して実装できます。以下で一つずつ分析していきます。



ConcurrentLinkedQueue

ロックフリー方式 (CAS+volatile) により、高同時実行シナリオに適したキュー。一般に、ConcurrentLinkedQueue のパフォーマンスは BlockingQueue よりも優れています。

これは、リンク ノードに基づく無制限のスレッドセーフ キューであり、先頭が最初に追加され、末尾が最後に追加されます。Null 要素は許可されません。追加されます。

add()/offer() はどちらも要素を追加するメソッドであり、違いはありません。poll()/peek() は head 要素を削除するメソッドであることに注意してください。ただし、poll は要素を削除します。しない。

他の通常のコレクションとは異なり、非ブロッキングの性質により、キューの SIZE を取得する方法には定数時間ではなく O(N) の時間がかかるため、サイズの使用をできるだけ避ける必要があることに注意することが重要です。可能な限り () メソッドを使用する場合は、代わりに isEmpty() を使用することを検討してください。

ロックを回避するために CAS+VOLATILE メカニズムが使用されていますが、理解する必要があるのは、これは、peek() などの 1 つの操作の安全性を確保するだけであり、複数の操作の安全性を確保したい場合は、同期効果を実現するにはロック機構を使用する必要があります。




BlockingQueue API

enqueue:


offer(E e): キューがいっぱいの場合はすぐに true を返し、キューがいっぱいの場合はすぐに false を返します。

put(E e): キューがいっぱいの場合、配列がいっぱいでなくなるかスレッドが中断されるまでブロックされます -->Blocking

offer(E e, long timeout, TimeUnit Unit): 要素を挿入しますキューの最後で、次の場合、配列がいっぱいになると、待機時間がタイムアウトになるまで待機します


デキュー:

poll(): データを取得するためにノンブロッキング、すぐに戻ります


take( ): データを取得するためにブロックします

poll(long timeout, TimeUnit単位): データを取得するために特定のタイムアウトでポーリングします



ArrayBlockingQueue


固定を維持する配列ベースのブロッキングキュー実装。データ オブジェクトを queue にキャッシュするために内部的に length 配列を使用します。ArrayBlockingQueue 内にはロック オブジェクト (ReentrantLock) が 1 つしかないため、読み取りと書き込みが分離されておらず、つまり、生成と消費を完全に並行することはできません。長さを定義する必要があるため、有界キューとも呼ばれます。




LinkedBlockingQueue

ArrayBlockingQueue と同様に、データ バッファ キュー (リンク リストで構成される) を内部的に維持します。

LinkedBlockingQueue が ArrayBlockingQueue より効率的に同時データを処理する理由は、内部実装が 2 つのロックを使用しているためです。これは、キューへの入り口とキューからの出口が別々にロックされること、つまり読み取りと書き込みが分離されていることを意味します。これにより、プロデューサーとコンシューマーが完全に Parallel に到達できるようになります。

長さを定義する必要はありません。無制限キューとも呼ばれます。もちろん、長さが定義されていない場合、キューの長さはデフォルトで Integer.MAX_VALUE であるため、プロデューサーの速度とコンシューマーの速度に注意する必要があります。




SynchronousQueue


バッファリングのないキュー。プロデューサーによって生成されたデータは、コンシューマーによって直接取得および消費されます。これは軽量のブロッキング キューです。容量がないため、使用に関しては、要素をフェッチする 1 つのスレッドによってのみブロックされ、別のスレッドが要素をキューに入れるのを待ちます。その後、要素はすぐにフェッチされます。実際、待機中のスレッドは、スレッド間での軽量の単一要素交換を実装します。




PriorityBlockingQueue

優先順位ベースのブロッキングキュー (優先順位はコンストラクターによって渡された Compator オブジェクトによって決定されます。つまり、キューに渡されたオブジェクトは Comparable インターフェイスを実装する必要があります)。

PriorityBlockingQueue を実装する場合、スレッド同期を制御するための内部ロックは、同じく無制限のキューである公平なロックを使用します。

平たく言えば、先入れ先出しのキューではなく、優先順位の低い人が先に出ます。すべての追加/オファーが並べ替えられるかどうかについて考えてみましょう。優先順位に従ってすべてを並べ替える必要がありますか?実際、add/take メソッドをざっと見てみると、PriorityBlockingQueue の設計思想が理解できます。追加するときはソートは実行されず、取得するときは優先度が最も小さいものを選択して取り出すだけです。これにより、追加時はソートに時間がかかりますが、取得時は完全にソートされずに優先度の低い要素のみが選択されるため、時間を節約できます。



遅延キュー


遅延時間付きのキュー。その中の要素は、指定された遅延時間が経過したときにのみキューから取得できます。キュー内の要素は Delayed インターフェイスを実装する必要があり、サイズ制限はありません。基本的に、遅延時間を優先して、PriorityBlockingQueue を利用して実装されます。遅延キューには、期限切れのキャッシュ データの削除、タスクのタイムアウトの処理、アイドル状態の接続の終了など、さまざまなアプリケーション シナリオがあります。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。