im trying to do the following:
- My program starts threads, which increment an
AtomicInteger
fromConcurrentHashMap<String, AtomicInteger>
and adds newInteger
toConcurrentHashMap<String, CopyOnWriteArrayList<Integer>>
. In that case, the size of theCopyOnWriteArrayList
is equal to the Value of theAtomicInteger
(of course for entries with the same key) - After all threads are done (when the
CountDownLatch
is finished) I try to convertConcurrentHashMap<String, AtomicInteger>
intoHashMap<String, Integer>
for sorting that Map by Value, becauseAtomicInteger
is not comparable. - After conversion I sort the
HashMap
by the Values and pick 20 entries with the highest value - in the sorted Map they are the first 20 entries. - Finally I pack the Values in an List and make JSON String with GSON.
Issue
What I expect: due my usage of AtomicInteger
, ConcurrentHashMap
and CopyOnWriteArrayList
I expect that all sizes and values for all entries with the same key are equal, even in my JSON String like:
myAtomcIntegerConcurrentHashMap.get("ABC").intValue() ==
myCOWArrayListConcurrentHashMap.get("ABC").size() ==
myNewHashMap.get("ABC")
But result seems be different. I made some console outputs to test my Values and got the following:
While copying from ConcurrentHashMap
to HashMap
I verify my values again. Every time the "bad copied" values are different (for the code snippet look below):
COWArrayList.size AtomicInteger.intValue Value in new HashMap
299 299 298
122 122 121
After that I iterate 4 more times over my new HashMap
to compare my values again and every time I get new random "bad copied" values (notice, the values were not detected while copying) (for the code snippet look below):
COWArrayList.size AtomicInteger.intValue Value in new HashMap Common Key
849 849 827 CGCCACC
838 838 813 GGTGGTG
My Json is also incorrect. E.g. for the Key "CGCCACC"
Size of my Array in Json is 887
, not like in the Table above (849
).
Here are code snippets I use (Some of them are from StackOverflow):
Incrementing AtomicInteger
and adding new Integer to CopyOnWriteArrayList
in my Threads:
//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();
Copy from ConcurrentHashMap<String, AtomicInteger>
to the HashMap<String, Integer>
each value (I guess its very inefficient) and immediate verifying:
//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()));
}
}
Verifying copied values of myHashMap
again (here I also get random "bad copied" values):
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()));
}
}
Why could that happen, have I missed something in my logic?
For further information / code etc. - just ask.
Thank you for helping me!