1

ソートされたデータ構造にたくさん書き込む必要がある同時シナリオがあります。Java ConcurrentSkipListMap:別のCollectionオブジェクトをアトミックに追加する

私はこの理由でConcurrentSkipListMapの使用について考えました。私の定義は次のようなものです:ConcurrentSkipListMap<K, List<V>>、最初の要素が挿入されたときにはもちろんList<V>の挿入を管理することは非常に困難です。

すなわち:もちろん

List<V> list = map.get(k); 
if (list == null) { 
    list = new LinkedList<V>(); 
    map.put(list); 
} 
list.add(v); 

これはアトミックではありません。クラスputIfAbsent()メソッドを使用して、それは非常に厄介で非効率的になるだろう:

List<V> newElement = new LinkedList<V>(); 
List<V> previous = map.putIfAbsent(k, newElement); 
if (previous != null) { 
    previous.add(v); 
} else { 
    newElement.add(v); 
} 

一つの方法は、自分自身のロックを作成し、通常のTreeMapを保護することはもちろんですが、私はこのオブジェクトの実際の高書き込み速度を持っているように、Iそれのために特別に設計されたものが好きです。もちろん、Pythonのcollections.defaultdictのようなものは完璧です。

+0

ロックされたコレクションまたは同期されたコレクションの使用が遅すぎることは知っていますか?どのくらい速くする必要がありますか? (できるだけ速いとは言わない) –

+0

私は基本的にこのデータ構造に書き込むだけで、concurrentskiplistmapはこの特定の側面で非常に効率的であり、書き込み時に並行性の良いレベルを可能にします。 TreeMap/RBTreeを使用すると、基本的には挿入ブロック全体がシリアルになります。 – marcorossi

+1

あなたはグアバのマルチマップを考えましたか? – fge

答えて

1

カップルのもの。

まず:あなたのプット-IF-不在のケースを処理するための最もeffecientな方法は、あなたがプット-IF-不在の場合のために得ることができるようeffecientある擬似ダブルチェック

public void add(Object key, Object val) { 
    List list = map.get(key); 
    if (list == null) { 
     list = new LinkedList(); 
     List temp = map.putIfAbsent(list); 
     if (temp != null) 
      list = temp; 
    } 
    list.add(val); 
} 

を行うことです。

2番目:リストに追加することで、ここで並行性の問題が解決しました。 LinkedListをCollections.synchronizedList()にラップしてマップに配置したい場合があります。

public void add(Object key, Object val) { 
     List list = map.get(key); 
     if (list == null) { 
      list = Collections.synchronizedList(new LinkedList()); 
      List temp = map.putIfAbsent(list); 
      if (temp != null) 
       list = temp; 
     } 
     list.add(val); 
    } 
+1

はい、質問の範囲外だったので、 'LinkedList'並行処理の問題について言及するのを忘れました。ありがとう! – marcorossi

関連する問題