キュー、キューのブロッキング

LinkedBlockingQueue:

出典:

サイズ/ **のブロッキングキュー、デフォルトではInteger.MAX_VALUEで* /民間最終int型の容量である; / **)* /民間最終のAtomicIntegerカウント=新のAtomicInteger(キュー内の要素の現在の数を遮断します。

*ブロックキューの先頭接合過渡ノード<E>ヘッド; *のブロッキングキューのテール・ノードのプライベート過渡ノード<E>最後; / **削除取得ロックなどなどテイク、世論調査、などの要素* /プライベート最終ReentrantLockのtakeLock =新しいReentrantLockの()。

 

特長:

1:デフォルトはInteger.MAX_VALUEであることをあなたが容量を指定しない場合:無制限キューである、(デフォルト値があるときは、削除速度よりも高速の大きなを追加した場合、それはメモリが不足することも可能です)。そのため、キューを避けるために、全負荷または表示されるようにメモリが多すぎることで、あなたのマシンを引き起こしました。

2:各データは、キューリストを追加、LinkedBlockingQueueノードはノードにカプセル化されるキューに追加されたヘッドと、ヘッドノードとテールノードキューに最後の点。

3:inkedBlockingQueue内部は、追加されtakeLockとputLock並行性制御を使用し、削除操作は、それが大幅にスループットを向上させることができるように、相互に排他的ではない操作を同時に行うことが可能です

 

 

エンキュー方法

無効プット(E e)は特徴:

1:キューは、ブロック待機いっぱいです。

2:キューはキューが行われ、スレッドが追加添加さ覚ますし続けるの隣、左側のスペースがある場合された後にキューにノードノードを作成し、いっぱいではありません。キューが要素の前に置かれていない場合は、消費者のスレッドの消費量の後に目覚めるために行われます。

公共のボイドプット(E e)のInterruptedExceptionある{(E == null)の場合は、新たにNullPointerExceptionを投げる()スロー; int型C = -1;ノード<E>ノード=新しいノード<E>(E);最終ReentrantLockのputLockはこれを=。 putLock;最終のAtomicIntegerカウント= this.count; //割り込み獲得ロックputLock.lockInterruptibly();試み{//キューが満杯であるかどうか、もし完全なブロッキング待機中(count.get()==容量){notFull。 await();キューエンキュー(ノード)へ} //ノード; C = count.getAndIncrement(); //キュー(C + 1であればスレッド覚醒追加操作がある場合、利用可能なスペースがあるかどうかを再度判定されます<容量)notFull.signal();}最後に{putLock.unlock();} //データキュー、消費のためにウェイクアップスレッド消費がある場合IF(C == 0)signalNotEmpty();}

 

プライベートボイドsignalNotEmpty(){最終ReentrantLockのtakeLock = this.takeLock。takeLock.lock(); {notEmpty.signal()試みます。}最後に{takeLock.unlock()。}}プライベートボイドsignalNotFull(){最終ReentrantLockのputLock = this.putLock。putLock.lock(); {notFull.signal()試みます。}最後に{putLock.unlock()。}}

 

ブール提供(Eのe)の特徴:

キュー要素が利用できない場合は、putメソッドを待っていると、障害物、プラン直接法メソッドはfalseと異なっています。

パブリックブールプラン(E E){場合(E == nullの)スロー新しいのNullPointerException();最終のAtomicIntegerカウント= this.count;場合(count.get()==容量)のリターンはfalse; int型C = -1;ノード<E>ノード=新しいノード<E>(E);最終ReentrantLockのputLock = this.putLock; putLock.lock();試み{//キュー・スペースが利用可能である、ノードにノードがに要素があるか否かを判断しますそうであれば、//、利用可能なスペース、次の加算までのスレッドウェイクを追加します。IF(count.get()<容量){エンキュー(ノード); C = count.getAndIncrement(); IF(C + 1 <容量)notFull.signal();}}最後に{putLock.unlock();}もし(C == 0)signalNotEmpty();戻りC> = 0;}

 

 

ブール提供(E電子、長いタイムアウト、TimeUnitで単位)特点:

タイムアウトを待つawaitNanosの条件を使用して、タイムアウト処理をブロックする方法を提供するには、なぜここにwhileループを使うのか?awaitNanos方法が待機しているスレッドが中断された時に防止するためには、割り込みされているので、ここではループが中断中の処理を待っている間に、残りは待つには長い待ち続け使います

 

デキュー方法

E take()特点:

1:キューが空である、ブロック待機。

2:キュー内の要素がある場合は、キュー、取得しから最初のチームを空にして要素を削除していない、ポスト消費者の下で、消費者のスレッド要素の除去は、目を覚ますし続けます。あなたがキューの前にケースを置いた場合の農産物のスレッドウェイク追加要素への使用後に取り除かれた要素がいっぱいです。

公共Eテイク()InterruptedExceptionある{Eは、Xスロー; int型C = -1;最終のAtomicIntegerカウント= this.count; ReentrantLockのtakeLock = this.takeLock最終; takeLock.lockInterruptibly();待機をブロックしながら試してみる{//キューが空であり、 (count.get()== 0){notEmpty.await();} X =デキュー(); C = count.getAndDecrement(); //キュー内の要素があり、次のウェイク消費のスレッド消費アップ(Cもし> 1)notEmpty.signal();}最後に{takeLock.unlock();} //削除要素をキューが一杯になる前に、生産スレッドは添加元素をウェイクIF(C ==容量)signalNotFull();戻りX; }

 

Eの世論調査():

パブリックEポール(){最終のAtomicIntegerカウント= this.count。(count.get()== 0)の戻り場合はnull; E、X = NULL; int型、C = -1; 最終ReentrantLockのtakeLock = this.takeLock。takeLock.lock(); (count.get()> 0){X =デキュー(){場合試みます。C = count.getAndDecrement()。IF(C> 1)notEmpty.signal(); }}最後に{takeLock.unlock()。} IF(C ==容量)signalNotFull(); 戻り値は、x; }

Eポーリング(長いタイムアウト、TimeUnitでユニット)

 

削除():削除要素法

パブリックブール削除(オブジェクトo){リターン偽(ヌル== O)場合; // 2つのロックはすべてfullyLockを()ロック;試み{//ヘッド素子からトラバース、(ノード<E>の最後の要素までトレイル=ヘッド、P = trail.next ;! P = NULL;トレイル= P、P = p.next){場合は、要素を削除するメソッドを呼び出して、同じ要素を発見//解除する場合(o.equals(p.item)) {リンク解除(P、トレイル); trueを返す;}}戻り偽;}最後に{//ロック解除2つのロック全てfullyUnlock();}}

 

-------------------------------------------------- -------------------------------------------------- -----------------------

 

ArrayBlockingQueue:

エンキュー方法:

1:追加:オファーは実際にキューがいっぱいになったとき、(「キューフル」)例外はブロックされませんIllegalStateExceptionがスロー、方法の中に入ります。

 

2:提供:フルキューは、trueを返し、リターン偽のキューがいっぱいになったとき。すぐにリターンをノンブロッキング。

、// ArrayBlockingQueue番号のオファーはフルでキューフル真、falseを返すパブリックブールのオファー(E電子){checkNotNull(e)を返す; //要素が空エンキュー最終ReentrantLockのロック= this.lockであるかどうかを確認してください。lock.lock (); // {ロック、スレッドセーフな試みを取得する場合(カウント== items.length)//キューがいっぱいになったとき、直接リターン偽リターン偽待ちをブロックしません。他に{INSERTの(e); //キュー一杯になっていません、直接リターンに真;}}最後に{lock.unlock();}}

プラン(E、時間、単位):データが指定した時間を返すの虚偽の、成功した挿入trueを返し以内キューに挿入することができない場合は、待機時間を設定します。  

 

3:PUT:キューは直接ではなく、戻り値に、満杯ではありません。キューが満杯でなくなるまで待ちキューブロックしますが、完全な、そして挿入待ちです。

// ArrayBlockingQueueの#プット

公共のボイドプット(E e)は例外:InterruptedExceptionをスロー{

  checkNotNull(E); //また、挿入要素が空であるかどうかをチェック

  最終ReentrantLockのロック= this.lock。

  lock.lockInterruptibly(); //ロックメソッドは、ここで呼び出されませんが、コールはlockInterruptibly中断することができ、中断されたリターンのスレッドとすることができる、ロックが復帰に中断することはできません。

  {試します

    しばらく(数== items.length)

      notFull.await(); //キューがスリープキューが非フルであるのでこと、いっぱいです

    (e)を挿入し; //この場合には、それは、要素内に挿入され、キューが満杯でない表している方法のきっかけに非空きキュー

  } 最後に {

    施錠開錠();

  }

}

 

デキュー方法:

1:削除():キューは、最初のチームの戻り値を空にして削除されません。キューが空ではNoSuchElementExceptionスロー()は例外であります

// AbstractQueue#削除、これはテンプレートメソッド、定義された削除アルゴリズムスケルトンキュー要素、およびキュー要素内の特定の要素は、要素が空で戻ると、例外がスローされ、特定の実装の世論調査は、サブクラスによって実装され、

パブリックE削除(){

  E、X =ポール(); //キューによって定義されたインタフェースメソッドをポーリング

  もし(X!= NULL)

    戻り値は、x;

  そうしないと

    新しいはNoSuchElementExceptionを投げます();

}

 

2:最初のチームの値と取り外し時にリターンキューが空ではありません。リターンがキューをゼロが空である:世論調査()。すぐにリターンをノンブロッキング。

// ArrayBlockingQueueの#ポーリング、待ち行列要素内のすべての要素を返し、(){最終ReentrantLockのロック= this.lockが空のヌル公共Eポーリングを返しません。lock.lock();試み{リターン(== 0を数えますか)?ヌル:エキス();}最後に{lock.unlock();}}

 

// ArrayBlockingQueue#抽出プライベートEエキス(){最終オブジェクト[]アイテム= this.items; E、X =この<E>キャスト(項目[takeIndex]);. //キュー要素項目の頭部を取り除く[takeIndex] = NULL ; //キューアレイ内の最初の要素を設定するには、ヌル、GCが容易である回復takeIndex = INC(takeIndex); --count; notFull.signal(); //待ちキューが非フルスレッドウェイクリターンXであり;}

世論調査(時間、単位):キューがない穴はnullが指定された時間内に返却されている場合、待機時間を設定し、チームはその後、空に最初の値を返していません 

 

3:テイク(E):最初のキューが空の戻り値チームや削除ではなく、キューが空のブロック待ち、キューが空の最初のチームの値に戻らないされるまでの待ち時間があるとき。 

// ArrayBlockQueue位(パブリックEテイクを取る)InterruptedExceptionある{最終ReentrantLockのロック= this.lockを()スロー; lock.lockInterrupted(); //このメソッドはロックに呼び出されていないが、通話がでlockInterruptibly中断することができる、方法ことスレッド割り込みを返すことができ、ロックが復帰に中断することはできません。してみてください{(カウント== 0)//キュー要素は空notEmpty.awaitは()である; //は、キューが空でないスリープ復帰エキス()で待つ; //この場合は、それが要素を削除され、キューが空でない表し、きっかけにしばらく非フルキュー}最後に{lock.unlock();}}

 

 

小拡張:

公共int型のサイズ(){最終ReentrantLockのロック= this.lock。lock.lock(); {リターン・カウントを試してみてください。}最後に{lock.unlock()。}}

方法ArrayBlockingQueueキューサイズは、カウント変数はConcurrentLinkedQueueは異なり、キューのConcurrentLinkedQueueサイズがより高いサイズメソッドConcurrentLinkedQueue効率より法ArrayBlockingQueueサイズので、各時間を通過し、直接戻されます。

 

サイズ()メソッド()コレクションを反復処理するためにサイズので()、のisEmptyよりも長くかかります。

 

 

 

SynchronousQueue

1:無制限では、各インサートは除去操作に対応する他のスレッドを待っている、またはその逆することが、非待機キューバッファです。SynchronousQueueそのような生産者と消費者は、チャンネルに参加するためには、このシナリオを「合格」「切」に適しているか、:スレッドが同期情報配信/時間/タスクにそれに他のスレッドを待たなければなりません。

 

2:いいえ内部SynchronousQueue容量がPEEKヘッダ要素法により取得することができない、単独の要素を挿入することができない挿入および除去は、「一組」対称操作であるように、それは単に理解することができます。特定の操作のコレクション(例えば含まれています)との互換性のために、SynchronousQueueは空のセットの役割を果たしました。

典型的なシナリオは、それを使用する上で)スレッドプール、Executors.newCachedThreadPool(中SynchronousQueueあり、必要に応じてアイドルスレッドがある場合は、スレッドプール(新しいタスクが来る)の構造は、新しいスレッドを作成し、スレッドを再利用されますこれは、60秒間アイドル状態にされた後に再利用されます。

 

3:糸の生産者や消費者の待機プロセスのためのSynchronousQueueオプションの公平性ポリシー(デフォルト以外の株式モード)。公正なモードを達成するために不当モードスタック(LIFO)は、キュー(FIFO)によって達成されます。データ構造は、二重キュー(デュアルキュー)とデュアルスタック(デュアルスタック)を使用し、FIFOは、典型的には、より高いスループットをサポートするために使用される、LIFOが高いスレッドローカルストレージ(TLS)をサポートしています。

次のようなアルゴリズムを遮断SynchronousQueueを要約することができます。

1:データを格納するデュアルキュー(デュアル・キュー)とデュアルスタック(デュアルスタック)を使用して、キュー内の各ノードは、プロデューサまたは消費者であってもよいです。

2:ゴミの保持及び記憶喪失を回避するために、それ自体にノード基準点をキャンセル

3:高競合環境下でスピンとLockSupport公園/ unparkを、によって達成ブロッキング、スループットが大幅に改善されたスピンであることができます。

 

3つの内部クラスがあります。SynchronousQueue

1:転写手段:内部抽象クラス、唯一の転送方法。SynchronousQueueを入れたり、統一プロセスを取る(これは転写法である)、デュアルキュー/スタックデータ構造ので、入れて取る動作はそうほとんどすべてのコードの、対称的で組み合わせることができるされています。

出典:

公共のボイドプット(E E)(E == nullが)(新しいNullPointerExceptionがスローする場合){例外:InterruptedExceptionがスローされます。IF(transferer.transfer(例えば、偽、0)== NULL){Thread.interrupted()。新しい例外:InterruptedExceptionを投げます(); }}

 

 

2:TransferStack:抽象クラスを継承内部転送手段は、LIFOデータの順に、非公平モードでのキュー操作のための転送方法を実現します。Sノードが達成方法リンクリストにより、デュアルスタックの内部。

モード)){//ヘッドノードは、(h.isCancelled())//既にキャンセル//ヘッドが一致した場合に履行しようと一致しようと一致していない、修飾されたヘッドは、ループcasHead(H、h.next)へと続きます。 //ポップリトライ//他のスタックであれば(casHead(H、S = Sノード(S、E、H、充実した|モード)))に新しいノードを構築一致するまで、{のための(;;){//ループまたはウェイターが成功試合後// CAS Sノードは、s.nextで消失すなわちM SノードM = s.next; // mは、Sの一致である(M == NULL){//すべての待機者がなくなっているcasHead(Sなら、 NULL); //新しいノード次回ブレークを使用; //メインループを再起動} SノードMN = m.next;(m.tryMatch(S)){//一致しようとした場合、ウェイクアップ//ノードs =ヌルを満たすポップスレッドcasHead Mノード(S、MN); //成功したマッチングつのノード、交換ヘッドの両方sおよびm個のリターン(E):;}((モード== REQUEST)をm.item s.item?)ポップポップ他//紛失一致s.casNext(M、MN); //一致ヘルプリンク解除を再循環させる、ノードmの削除、失敗}}}他{最初のノードが助けを一致させる// fulfiller SノードM = h.next; // (M == NULL)//ウェイターが現金を行っている場合、mは時間の試合で EAD(H、NULL); //他の充実ノードをポップ{//帮助头节点匹配SノードMN = m.next。もし(m.tryMatch(H))//ヘルプ一致casHead(時間、MN); //両方ともHをポップし、//ロスト一致h.casNext(M、MN)他mは、//ヘルプのunlink}}}}

 

説明:基本的なアルゴリズムは、3サイクルの一つであり、次の動作を試してみてください。

1:スタックが空であるか、既に同じMODEが含まれている場合は、この時点では2例です:非カウント動作(募集、ポーリング)、または有効期限が切れた、ダイレクトリターンnullの場合は、他の例では、現在のノードが押されたスタック待ちに入れますノードはクリーン方法にコールウェイティングをキャンセルした場合(awaitFulfill法により)一致、マッチは、アイテムの一致するノードを返されたヌルをキャンセルして返すために待機ノードをクリアする(別途後述)。

2:スタックノード(ヘッド)、(isFulfilling法により決定)マッチスタック現在のノードに入れ、ノードはヘッドに一致しようとしていない場合、2つの整合ノードが正常スタックから排出され、そしてデータ照合ノードを返します。次のようにソースコードをisFulfilling:

mは、ビットセットを満たしている場合は/ ** trueを返します。* /静的ブールisFulfilling(INT M){リターン(M&満たす)!= 0; }

3:スタックノード(ヘッド)の上部がすでにスタック・ノードが一致することを示す、別のデータノードを保持している場合、マッチング動作は、このノードを助け、次にサイクルは最初のステップから継続開始します。

 

3:TransferQueue:抽象クラスを継承内部転送手段は、FIFOデータの順に、公平キュー動作モードの転送方法を実現します。道リンクリストキューによって二重の内部QNodeを実現します。

出典:E転送(E電子、ブール値は時限、長いnanos値){QNode S = NULL; //構築/必要なブールisData =(!E = NULL)として再利用; //分析プットまたはのために取る(;;){QNode T =尾; QNode H =ヘッド(T == NULL || H == NULL)//鋸初期化されていない値が続く場合; //スピンIF(H == T || t.isData == isData){//空または同じモードQNode TN = t.next;(!T =尾)//矛盾読み出しが続けば、IF(!TN = NULL){//ヒステリシステール・ノード、尾advanceTailを遅れテール・ノードを更新(T、TN) ;続ける;}(時限&& nanos値<= 0)//戻りヌルを待つことができない場合は、新しいノードの//現在の動作構成、および尾部にあれば(S == NULL)S =新しいQNode(E、 isData)); //継続中のリンクに失敗した場合(!t.casNext(nullのは、S); //事前テールadvanceTail(tは、S); //スイングテールと待機//待機一致、およびリターンマッチしたノードアイテム、このノードが待機SキャンセルオブジェクトX = awaitFulfill(S、Eは、nanos値をタイミング)場合はリターン;(x == S)場合は{//待機クリーン(T、S)キャンセルされた; //待機が解除されるように、クリアSノード戻りNULL;}(S場合!ヘッド場合IF(X = NULL)//リンクを解除し、それ自体にフィールドs.item = S ;! //アイテムを忘れ; isOffList()){//のノードがまだ既にadvanceHead(T、S)をリンク解除しないデキューしていませんs.waiter = NULL;}リターン(X =ヌル!)(E)X:E; //取る}他{//相補モードQNode M = h.next;(T =場合//ノードが果たすため! !尾||メートル== nullの|| H =ヘッド)継続; //一貫性のない読み込みオブジェクトのx = m.item;(もし!isData ==(X = NULL)|| //メートルすでに成就のx ==メートル| | //m.item=m、mはm.casItem(X、E)){//一致をキャンセルし、CASはに進み、CAS advanceHead(H、M);! //推進ヘッドを失った所定の要素eの項目を変更しデキュー再試行を発見した後に続け;} advanceHead(H、M); //成功したマッチ、ヘッドが正常に成立デキューLockSupport.unpark(m.waiter); // Mウェイクアップノードが一致するスレッドリターン(!X = NULL) ?(E)X:E;}}}?}復路(E)X(X = NULL!):E; //テイク}他{//相補モードQNode M = h.next; //ノードは==場合(T =尾|| Mを満たすために! !ヌル|| H =ヘッド)続ける; //矛盾読み出し対象X = m.item;(!isData ==(X = NULL)|| // mは既にX == M || //m.item満たした場合!= M、Mキャンセルm.casItem(X、E)){//一致、CASは、CAS advanceHead(H、m)を失った所定の要素eの項目を変更し; //事前ヘッド後方デキューを見続けて再試行を続行?;} advanceHead(H、M); //成功したマッチ、ヘッドが正常に成立デキューLockSupport.unpark(m.waiter); // Mウェイクアップノードが一致するスレッドリターン(X =ヌル!)(E)X: E;}}}?}復路(E)X(X = NULL!):E; //テイク}他{//相補モードQNode M = h.next; //ノードは==場合(T =尾|| Mを満たすために! !ヌル|| H =ヘッド)続ける; //矛盾読み出し対象X = m.item;(!isData ==(X = NULL)|| // mは既にX == M || //m.item満たした場合!= M、Mキャンセルm.casItem(X、E)){//一致、CASは、CAS advanceHead(H、m)を失った所定の要素eの項目を変更し; //事前ヘッド後方デキューを見続けて再試行を続行?;} advanceHead(H、M); //成功したマッチ、ヘッドが正常に成立デキューLockSupport.unpark(m.waiter); // Mウェイクアップノードが一致するスレッドリターン(X =ヌル!)(E)X: E;}}}E)){//一致は、CASはCAS advanceHead(H、M)失われた指定された要素eの項目を変更し; //事前ヘッドは、後方にデキュー再試行を続ける見続けて;} advanceHead(H、M); //マッチング成功した、ヘッドが正常LockSupport.unpark(m.waiter)が満たさデキュー;(!X = NULL)// Mウェイクアップノードが一致するスレッドのリターンを(E)X:?E;}}}E)){//一致は、CASはCAS advanceHead(H、M)失われた指定された要素eの項目を変更し; //事前ヘッドは、後方にデキュー再試行を続ける見続けて;} advanceHead(H、M); //マッチング成功した、ヘッドが正常LockSupport.unpark(m.waiter)が満たさデキュー;(!X = NULL)// Mウェイクアップノードが一致するスレッドのリターンを(E)X:?E;}}}

 

説明:基本的なアルゴリズムは、次のアクションを介して2つのサイクルのいずれかです。

1:キューが空であるか、キュー(テール)とその同じモードでのテール・ノードは、現在のノードがキューの終止符を打つために追加されている場合は、キャッチホンawaitFulfillノードが一致しています。ノードが中断または待機待ちタイムアウト戻るヌルである場合、リターンマッチは、ノードの項目に一致しています。一方で、我々は、テール・ノードが他のスレッドによって変更された場合、サイクル後方推進尾に進み、その後、テール・ノードをチェックしていきます。

注:TransferStack.awaitFulfillアルゴリズム、背中と一致awaitFulfill方法のTransferQueueは、もはや説明されています。

2:テール・ノード(尾)の現在の動作モードが異なる場合、一致させることができ、キューの先頭からヘッドノードは、ノードが所与の素子Eによって相補型電界CAS項目を変更しようと相補ノードと一致後方に探し始めるために、一致が後方にヘッド前進、及びマッチングノードウェイタースレッド、及び最終的に戻された項目の一致するノードをウェイクアップされた場合。

 

比較スタック/キューノードクリアランス(方法クリーン)

1:ノードがキャンセルされた場合、キューのために、私たちはほとんど常にノードの複雑な時間-O1度が削除されたことができます。しかし、尾のノードならば、それは後でノードをキャンセル待たなければなりません。

2:スタックについて、我々はスタック全体を横断するO(N)の時間計算量を必要とし、そのノードを除去することができるかを決定するが、他のスレッドが並列にスタックおよび実行にアクセスすることができてもよいです。

 

 

 

 

 

 

 

-------------------------------------------------- -------------------------------------------------- -----------------------

要約:

LinkedBlockingQueueは、スレッドセーフとそれぞれの条件で実施したキュー、のうちのawaitと、信号待ちやウェイクアップ機能をオブジェクト達成するために内部的に2つのReentrantLockのでキューブロックしています。これは、そのArrayBlockingQueueに異なります。

  • キューサイズは、添加速度は中、除去速度よりも大きい場合、後者のために、指定されなければならない制限されたサイズとArrayBlockingQueueを初期化するが、LinkedBlockingQueueは(Integer.MAX_VALUEの)非有界であってもよい囲まれてもよく、異なってい無制限の場合は、メモリのオーバーフローやその他の問題を引き起こす可能性があります。
  • 異なるデータ・ストレージ・コンテナ、データ格納容器とArrayBlockingQueueとしてアレイを使用して、そしてLinkedBlockingQueueノードがオブジェクトのリンクされたリストのノードとして使用基づいています。
  • 貯蔵容器はArrayBlockingQueueアレイを用いているため、破壊するように追加の又は任意のオブジェクトインスタンス要素が挿入されていないまたは削除が、追加LinkedBlockingQueueノードオブジェクトが生成されます。それは長い時間がかかることがあり、高いです
  • 大量のデータの同時効果を処理したとき、GCのための大きな影響があってもよいです。
  • ロックキューが別LinkedBlockingQueueを実施している間キューは、ArrayBlockingQueueロック単離されていないが、ロック操作が付加され、操作ReenterLockが採用除去実装され、両方の追加または削除、ロック待ち行列が同じではありません達成、putLockを追加するために使用され、takeLockを除去するために使用され、これは非常に、キューのスループットを増加させることができる生産者と消費者が高い同時の場合にはパラレルデータキューで動作することができることを意味しますキューの全体的なパフォーマンスを向上させるために、この同時実行。

 

公開された50元の記事 ウォンの賞賛2 ビュー2342

おすすめ

転載: blog.csdn.net/eafun_888/article/details/93044980