ConcurrrentMapの分析と思考

3416 ワード

予備知識でhashmapの記憶構造が分かります.
   
(画像からhttp://www.ibm.com/developerworks/cn/java/j-lo-hash/)
つまり、一つのhashmapの内部にはEnttityクラスの行列が含まれています.この配列の要素は全部Entityです.実際にmapに入れたkeyとvalueは一つのEntityオブジェクトに対応しています.このEntityオブジェクトは一つのkey、value、hashcodeと一つのEntityの参照を含んでいます.この参照によってEntityはチェーンテーブルを形成することができます.図では、青い四角形のブロックは配列を表し、オレンジ色の楕円はEntityオブジェクトを表しています.
注意HashMap類はスレッド安全ではありません.
コンカレントMap  主なサブクラスはコンカレントHashMapです.
原理:一つのConcerenthashMapは複数のsegmentからなり、各segmentは一つのEntityの配列を含みます.ここはHashMapよりsegment類が一つ多いです.このクラスはRentrant Lock類を継承していますので、自身はロックです.マルチスレッドがConcerenthashMapに対して動作するときは、mapを完全にロックするのではなく、対応するsegmentをロックします.これによって合併効率が向上しました.
構造関数の分析:
[java]view play copy print?
//*
  •      * Creates a new,empty map with a default initial capacity(16)、
  •      * load factor(0.75)and concurrencyLevel(16).
  •      */ 
  •     public ConcerenthashMap(){ 
  •         this(DEFAULTU_INITIAL LuCAPACITY、DEFAULT_LOAD FACTOR、DEFAULT_CONCURRENCYUVEL); 
  •     }  //Creates a new、empty map with a default initial capacity(16)、*load factor(0.75)、and concurrencyLevel(16)、*/public ConcerenthashMap(){this(DEUFLTty INITIALuCACITY,DECTULTU)
    これはコンカレントHashMapの無参画構造関数であり、デフォルトの大きさは16、負荷因子は0.75、同時レベルは16と見られます.
    Put関数の分析:
    [java]view play copy print?
    //*
  •      * Maps the specified key to the specified value in this table.
  •      * Neither the key nor the value can be null.
  •      *
  •      * The value can be retrieved by caling the get method
  •      * with a key that is equal to the original key.
  •      *
  •      * @param key with which the specified value is to be assicated
  •      * @param value value to be assicated with the specified key
  •      * @return the previous value assciated with key,or
  •      *         null if there wasのmapping for key
  •      * @throws Null PointerException if the specified key or value is null
  •      */ 
  •     public V put(K key,V value){ 
  •         if(value==null) 
  •             throw new Null PointerException() 
  •         int hash=hash(key.hashCode); 
  •         return segmentFor.put(key,hash,value,false); 
  •     }  Maps the speciiifrid key to the speciiiiiifd value in thistablble*Neither the key nor the value can be null.*The value can be retrieved bycalcarived the get method*with a key aaaaaaaaaththththisisaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasasasasasasasasasato be assicated with the specified key@return the previous value asassited with key、or*null if there wasのmapping forkey*@throws Null Point Exception ithe speciiiiiifed or value isnull*/public V put(K key、V valuint=valuint============vavaluefffftttttttttttttttfffffffffffffffttttttttttttttttttttffffffffffffffffffffffffsegmentFor.put(key,hash,value,false);
    hash()関数によってkeyのハッシュ値が得られ、対応するsegmentが得られ、segmentによってEntityが格納されていることが分かる.
    また、「再検出」(条件付きスレッド安全参照[2])などの合併問題を避けるために、ConcerenthashMapはputIfAbsent(K key,V value)を提供しています.  方法は、keyが存在しない場合に追加します.(keyの存在は二つの条件、一つはkeyのhashcode方法、もう一つはkeyのequal方法です.)
    長所:対応するsegmentのため  全体のmapをロックするのではなく、ロックをかけて、合併性を高めました.挿入、検索、除去操作の伸縮性を直接高めることができます.
    短所:mapの要素を遍歴するときは、全てのsegmentのロックを取得して、遍歴を使用すると遅くなります.ロックの増加は、システムのリソースを占有します.このセット全体を動作させるいくつかの方法(例えば、 size()またはisEmpty())があります.これらの方法は多くのロックを一度に獲得することが必要であり、また不正な結果を返すリスクがあるからです.