3 回答
TA贡献1802条经验 获得超5个赞
ConcurrentHashMap 是线程安全的,可以保证每一个操作都是线程安全的。
但是这些操作不是原子的:
if (!wordOccurrencesMap.containsKey(word)) {
pair = new Pair<>(word, 1);
//System.out.println(Thread.currentThread().getName() + " Creating Pair: " + pair);
} else {
pair = wordOccurrencesMap.get(word);
pair.setValue(pair.getValue() + 1);
//System.out.println(Thread.currentThread().getName() + " Updating Pair: " + pair);
}
wordOccurrencesMap.put(word, pair);
您可以改为使用单个操作:
wordOccurrencesMap.compute(word,
(s, pair) -> pair == null ?
new Pair<>(word, 1) : pair.setValue(pair.getValue() + 1));
TA贡献1843条经验 获得超7个赞
好吧,添加可以synchronized(this)解决问题,但是您将失去多线程和并行化的所有好处。
你需要的是 的computeIfAbsent方法ConcurrentMap。所以你的for循环体将转换为
Pair<String, Integer> pair = wordOccurrencesMap.computeIfAbsent(word, w -> new Pair<>(w, 0));
synchronized(pair) {
pair.setValue(pair.getValue()+1);
}
现在你可以省略你的synchronized(this)块。
编辑:但是您必须确保当第一个线程调用pair.setValue() 时,没有另一个线程可以调用pair.getValue(),如注释所述。
添加回答
举报