コンカレント・コンテナー(論文のコピー)



説明:JavaGuideから転載ブログ、に等しい(または再び練習の独自のマニュアルを持っています)


1.概要

JDKはjava.util.concurrentの提供コンカレント・コンテナー、あの有名なJUCは、以下のとおりです。

  • ConcurrentHashMapの:HashMapのスレッドセーフ
  • CopyOnWriteArrayListと:スレッドセーフリスト
  • ConcurrentLinkedQueue:効率的な同時キュー、キュー、スタックの比較
  • BlockingQueueの:インターフェース:リンクされたリストによって実装さ、配列等は、共有データチャネルのためのキューをブロック表します
  • ConcurrentSkipListMapの:地図でジャンプテーブルの実装、迅速なルックアップテーブルジャンプのために使用されるデータ構造








2.のConcurrentHashMap

CASは、並行性を向上させる前のセグメントに比べて、並行性を使用し、安全性を確保するために同期、最初のノードを書き込むときに差分のみロックされている限り、衝突が発生しないように、それは同時ではないであろう。利用底部:ノード配列+リスト/黒の木








3. CopyOnWriteArrayListと

毎日、私たちは、大部分を占め、あまり書きされているの多く読ま。我々はデータを読み、複数のスレッドへの同時アクセスを許可するように、毎回場合は、読み取り操作ロックは、無駄であるだけでなく、唯一の同期待機する必要があり、読み取り操作、書き込みと書き込みとをブロックせずに書きます。


コピーオンライト:あなたはメモリのブロックを変更したい場合は、コンピュータの後、我々はメモリの元のブロックに含まれていない書かれているが、メモリコピー、新しいメモリー内の書き込み操作、それを終了へ新しいメモリに元のメモリポインタを指すようになります、元のメモリをアウトに回収することができます


すべての変数の操作CopyOnWriteArrayListとクラス(追加、設定など)を達成するための基本となる配列の新しいコピーを作成することです。名前で:コピーを書くとき。リストの必要性を変更するとき、私は元のコンテンツを変更しないが、元のデータのコピーが、変更はコピーを書かれています。書き込み後は、その後、改訂されたので、あなたがその書き込みを確保できる操作は読み取り動作には影響しません、データの元のコピーを置き換えます


例えば、addメソッドを書きます

public boolean add(E e) {
    
    // 需要手动的锁机制,并发知识
    final ReentrantLock lock = this.lock;
    lock.lock();
    
    try {
        // 这里其实看代码就能知道怎么回事了
        Object[] elements = getArray();
        int len = elements.length;
        Object[] newElements = Arrays.copyOf(elements, len + 1);
        newElements[len] = e;
        setArray(newElements);
        return true;
    } finally {
        lock.unlock();
    }
}

注:レプリケーションが必要な場合は、ロックは、マルチスレッド複数のコピーを避けます








スレッドセーフなキューJavaは、に分けることができ提供キューブロッキング非ブロッキングキューブロッキングキューBlockingQueueの、ConcurrentLinkedQueueは、実用的なアプリケーションで実際の必要に応じてキューキューブロッキングまたは非ブロッキングに使用する非ブロッキングキューの典型的な例の代表例です、 。キューがロックを遮断することによって達成することができる、CASは、非ブロッキング操作キューによって実現されてもよいです。

4. ConcurrentLinkedQueue

CASの内部の使用は、マルチスレッドアクセスのためのキューを実装し、そして時間をロックするコストが高いことです。CASは、同時ロック属し、その背中に紹介するブログを書くことをするとき、私は内容を確認したよう








我々はすでに、高性能ノン・ブロッキングConcurrentLinkedQueueキューとして上に言及しています。今、私たちは、キュー--BlockingQueueをブロックしているアドレスにしたいです。ブロッキングキュー(BlockingQueueの)が広く「生産者 - 消費者」で使用されている問題、理由はBlockingQueueの挿入および除去の方法を阻止することができる提供しています。キューコンテナがいっぱいになると、キューが満杯でなくなるまで、生産者スレッドはブロックされます。キューは、コンテナを空になったとき、消費者のスレッドがブロックされ、キューが空ではありませんアップまで

5. BlockingQueueの

BlockingQueueのキューから継承されたインターフェイスであるので、その実装クラスは、キューの実装としても使用することができ、およびキューもCollectionインタフェースから継承されました。ここではBlockingQueueの関連する実装クラスは次のとおりです。

  • ArrayBlockingQueue
  • LinkedBlockingQueue
  • PriorityBlockingQueue


5.2 ArrayBlockingQueue

ArrayBlockingQueueは根底にある使用して、有界キューBlockingQueueのインタフェースの実装クラスである配列が達成されます。ArrayBlockingQueueを作成したら、容量を変更することはできません並行性制御を使用しているリエントラントロックコントロール、挿入操作または読み出し操作か、動作するロックを獲得するためにすべての必要性。キューがフル稼働である場合には、キューに入れてみてくださいオペレーティング要素がブロッキングを起こします。空のキューから要素を削除しようとする試みがされますまた、ブロック

スレッドがキューにアクセスのArrayBlockingQueueデフォルトは公平性を保証することはできません、いわゆる公平性がArrayBlockingQueueに最初のスレッドの最初の訪問を待つことができます厳密に従っ待機中のスレッドに絶対年代順を指します。公平性はArrayBlockingQueue厳密な年代順に従わないシーケンシャルアクセスを意味するのではなくArrayBlockingQueueにアクセスできる場合、ブロックされたスレッドが依然としてArrayBlockingQueueにアクセスできない長時間、存在してもよいです。保証公正た場合、一般的にスループットが低下します。あなたはArrayBlockingQueueの公平性を必要とする場合は、次のコードを使用することができます。

private static ArrayBlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(10,true);


5.3 LinkedBlockingQueue

LinkedBlockingQueueの上の底片方向リンク・リストのキューがブロッキング実装境界として無制限キューとしてキューに入れることができるが使用され得るそれらとArrayBlockingQueueと比べてスループット容量LinkedBlockingQueue損失の急激な増加を防止するために、より高いと、FIFOの同じ特性を満たすために、多くのメモリ。あなたがオブジェクトを作成するときに指定されていない、容量にInteger.MAX_VALUEに等しい場合、通常LinkedBlockingQueueは、サイズを指定します


5.4 PriorityBlockingQueue

PriorityBlockingQueueは、無制限のブロッキングキュー-優先事項です。自然の要素を使用して、デフォルトのソート順によって、カスタムクラスによって実装されてもよいcompareTo()、または初期化パラメータ構築することにより、照合方法の要素を指定するには、Comparator照合を指定します。

PriorityBlockingQueue並行性制御用途ReentrantLockのの、キューが制限されるとキューがアンバウンド形式のキュー(ArrayBlockingQueue、LinkedBlockingQueue容量がコンストラクタ内の着信キューの最大容量によって指定のみ初期PriorityBlockingQueueキューのサイズを指定することができるされ、要素が後ろに挿入とき、スペースが十分でない場合は、自動的に拡大)。

簡単に言えば、それは優先度つきキューのスレッドセーフバージョンです。オブジェクトがキューに挿入されながら、同等の大きさ(匹敵)である必要があり、NULL値を挿入する、または異常ClassCastExceptionが報告されていないことができます。それはアンバウンド形式のキュー(待ち行列がブロックされたときに取るメソッドは空になります)ですので、挿入方法はブロックしません置きます。








6. ConcurrentSkipListMapの

どのような簡単なジャンプテーブルを理解するために皆をもたらすために、ConcurrentSkipListMapのを誘発するために。

我々は唯一の最初から最後まで、リストをトラバースすることができ、データを検索する場合、単一リンクリストは、リストが注文された場合でも、その効率は当然低くなると、ジャンプテーブルは同じではありません。ジャンプテーブルは、バランスのとれたツリーに幾分類似し、迅速に検索するために使用することができるデータ構造です。彼らはすぐに要素を見つけることができます。しかし、重要な違いがある:バランスの取れたツリーの挿入や削除のために、多くの場合、おそらくグローバル調整後はバランスの取れたツリーにつながることがあります。ホップの挿入や削除のテーブルは、ローカルデータ構造の全体を操作する必要がありますが。このような利点は次のとおりです。高い同時実行の場合には、あなたは木のバランス全体でスレッドの安全性を保証するためにグローバルなロックが必要になります。ジャンプテーブルの場合は、あなただけのロック部に必要です。このように、非常に同時環境の中で、あなたはより良い性能を持つことができます。そして、クエリのパフォーマンスの面で、時間複雑ジャンプテーブルがあるO(LOGN)の同時データ構造ので、JDK地図を達成するためにジャンプテーブルを使用して


自然のジャンプ台が同時に複数のリストを維持しており、リストは階層的です、

ジャンプテーブルのすべての要素のリストを維持するための最低レベルは、それぞれ上部層は、以下のリストのサブセットの層です。

ジャンプテーブル内のリストのすべての要素がソートされます。とき検索は、あなたが上から順にリストを見つけることができます。求められている要素は、リストの現在の値よりも大きくなると、リストは、次のレベルに転送されます、探し続けます。この手段の検索時に、検索は飛躍的であること。上記のように、要素18は、ジャンプテーブルを見つけます。

オリジナルの必要性が18を通過する際に18を検索し、今は7回を取ります。リストの長さについてインデックスは非常に明白であろう効率を向上しようとするときに大きなビルド。

容易に上から見た、ジャンプテーブルは、時間アルゴリズムのためのスペースを使用することです。

利用ジャンプテーブルの実装では、地図と地図ハッシュアルゴリズムの間に別の違いがあるさ:ハッシュは、要素の順序は保存されませんし、ジャンプテーブル内のすべての要素がソートされます。テーブルを横断するジャンプする際にそのため、あなたは注文した結果を得るでしょう。アプリケーションが整然と必要があれば、その後、ジャンプテーブルは、あなたの唯一の選択肢です。このデータ構造が実装されているJDKのクラスがConcurrentSkipListMapのです。




おすすめ

転載: www.cnblogs.com/Howlet/p/12517439.html