私は次のことをしようとしています:
AtomicInteger
私のプログラムは、 fromをインクリメントし、 newを にConcurrentHashMap<String, AtomicInteger>
追加するスレッドを開始します。その場合、 のサイズはの値と等しくなります (もちろん、同じキーを持つエントリの場合)。Integer
ConcurrentHashMap<String, CopyOnWriteArrayList<Integer>>
CopyOnWriteArrayList
AtomicInteger
- すべてのスレッドが完了した後 (が終了したとき) 、そのマップを値でソートするために
CountDownLatch
変換しようとします。比較できないためです。ConcurrentHashMap<String, AtomicInteger>
HashMap<String, Integer>
AtomicInteger
- 変換後、値で並べ替え、
HashMap
値が最も高い 20 エントリを選択します。並べ替えられたマップでは、それらは最初の 20 エントリです。 - 最後に、値をリストにパックし、GSON で JSON 文字列を作成します。
問題
私が期待すること: の使用により、AtomicInteger
同じ キーを持つすべてのエントリのすべてのサイズと値が、次のような JSON 文字列であっても等しいと予想されます。ConcurrentHashMap
CopyOnWriteArrayList
myAtomcIntegerConcurrentHashMap.get("ABC").intValue() ==
myCOWArrayListConcurrentHashMap.get("ABC").size() ==
myNewHashMap.get("ABC")
しかし結果は違うようです。値をテストするためにいくつかのコンソール出力を作成したところ、次の結果が得られました。
ConcurrentHashMap
からにコピーしている間HashMap
、値を再度確認します。「不正にコピーされた」値が異なるたびに (コード スニペットについては、以下を参照してください):
COWArrayList.size AtomicInteger.intValue Value in new HashMap
299 299 298
122 122 121
その後、新しいものをさらに 4 回繰り返しHashMap
て値を再度比較し、新しいランダムな「不適切なコピー」値を取得するたびに (コピー中に値が検出されなかったことに注意してください) (以下のコード スニペットを参照してください)。
COWArrayList.size AtomicInteger.intValue Value in new HashMap Common Key
849 849 827 CGCCACC
838 838 813 GGTGGTG
私のJsonも間違っています。"CGCCACC"
たとえば、Json の配列のキーサイズは であり887
、上記の表 ( 849
) とは異なります。
私が使用するコード スニペットは次のとおりです(一部は StackOverflow からのものです)。
スレッドに新しい整数をインクリメントAtomicInteger
して追加する:CopyOnWriteArrayList
//Add new Integer 'position' to the COWArrayList from 'positions' with the key 'frame'
List<Integer> copyArr = positions.get(frame);
if (copyArr == null) {
copyArr = new CopyOnWriteArrayList<Integer>();
List<Integer> inMap = positions.putIfAbsent(frame, (CopyOnWriteArrayList<Integer>) copyArr);
if (inMap != null) copyArr = inMap; // already in map
}
copyArr.add(position);
//Increment the AtomicInteger from 'scores' with the key 'frame'
AtomicInteger value = scores.get(frame);
if (value==null){
value = new AtomicInteger();
AtomicInteger actual = scores.putIfAbsent(frame, value);
if(actual != null) value = actual;
}
value.incrementAndGet();
ConcurrentHashMap<String, AtomicInteger>
から各値にコピーしHashMap<String, Integer>
(非常に非効率的だと思います)、すぐに検証します:
//init new, non-concurrent Map
Map<String, Integer> myHashMap = new HashMap<String, Integer>();
//iterate over the Map and copy each value from 'scores' to 'newHashMap'
for(Map.Entry<String, AtomicInteger> score : scores.entrySet()){
myHashMap.put(score.getKey(), score.getValue().intValue());
//verify just added Value and print values of all Maps if something is wrong
if(score.getValue().intValue() != myHashMap.get(score.getKey())){
System.out.println(score.getValue().intValue() + " " + positions.get(score.getKey()).size() + " " + myHashMap.get(score.getKey()));
}
}
コピーされた値を再度確認しますmyHashMap
(ここでは、ランダムな「不適切なコピー」値も取得します):
for(Map.Entry<String, AtomicInteger> score : scores.entrySet()){
if(score.getValue().intValue() != myHashMap.get(score.getKey())){
System.out.println(score.getValue().intValue() + " = " + positions.get(score.getKey()).size() + " =? " + myHashMap.get(score.getKey()));
}
}
なぜそれが起こるのか、私の論理で何かを見逃したのでしょうか?
詳細情報/コードなどについては、お問い合わせください。
助けてくれてありがとう!