AtomicInteger
增加ConcurrentHashMap<String, AtomicInteger>
并将新Integer
添加到ConcurrentHashMap<String, CopyOnWriteArrayList<Integer>>
。在这种情况下,CopyOnWriteArrayList
的大小等于AtomicInteger
的值(当然对于具有相同键的条目)CountDownLatch
完成后)我尝试将ConcurrentHashMap<String, AtomicInteger>
转换为HashMap<String, Integer>
,以便按地理位置排序,因为AtomicInteger
无法比较HashMap
并选择20个值最高的条目 - 在排序后的地图中,它们是前20个条目。问题
我的期望:由于我使用了AtomicInteger
,ConcurrentHashMap
和CopyOnWriteArrayList
我希望所有具有相同键的条目的所有大小和值都相等,即使在我的JSON字符串中也是如此像:
myAtomcIntegerConcurrentHashMap.get("ABC").intValue() ==
myCOWArrayListConcurrentHashMap.get("ABC").size() ==
myNewHashMap.get("ABC")
但结果似乎有所不同。我做了一些控制台输出来测试我的值并得到以下结果:
从ConcurrentHashMap
复制到HashMap
时,我会再次验证我的值。每次&#34;坏复制&#34;值是不同的(对于下面的代码片段):
COWArrayList.size AtomicInteger.intValue Value in new HashMap
299 299 298
122 122 121
之后,我再次在我的新HashMap
上再迭代4次以再次比较我的值,每次我得到新的随机数&#34;糟糕复制&#34;值(注意,复制时未检测到值)(对于下面的代码片段):
COWArrayList.size AtomicInteger.intValue Value in new HashMap Common Key
849 849 827 CGCCACC
838 838 813 GGTGGTG
我的Json也不正确。例如。对于Json中我的数组的键"CGCCACC"
大小为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
的复制值(此处我也随机获得&#34;错误复制&#34;值):
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()));
}
}
为什么会发生这种情况,我的逻辑错过了什么?
有关更多信息/代码等 - 请问。
感谢您帮助我!
答案 0 :(得分:1)
似乎AtomicInteger
通过调用AtomicInteger.incrementAndGet()
增量事件来解决问题。我的线程正在调用该函数〜3.5 Mio次,而Queue是巨大的。线程完成后,主线程立即复制ConcurrentHashMap
的{{1}},但某些AtomicInteger
的队列并不完整。这就造成了不一致。
我通过给AtomicIntegers
一些时间来完成它来解决这个问题&#34;增加队列&#34;完成所有线程后。
AtomicInteger
瞧!没有不一致了!
如果有另一种方法等待 try {
myCountDownLatch.await();
Thread.sleep(5000); //let AtomicInteger finish they incrementations
} catch (Exception e) {
System.err.println("Error in a Latch Countdown: " + e.toString());
}
完成增量队列,我会很感激阅读。