3 回答

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超5個(gè)贊
ConcurrentHashMap 是線程安全的,可以保證每一個(gè)操作都是線程安全的。
但是這些操作不是原子的:
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);
您可以改為使用單個(gè)操作:
wordOccurrencesMap.compute(word,
(s, pair) -> pair == null ?
new Pair<>(word, 1) : pair.setValue(pair.getValue() + 1));

TA貢獻(xiàn)1843條經(jīng)驗(yàn) 獲得超7個(gè)贊
好吧,添加可以synchronized(this)解決問題,但是您將失去多線程和并行化的所有好處。
你需要的是 的computeIfAbsent方法ConcurrentMap。所以你的for循環(huán)體將轉(zhuǎn)換為
Pair<String, Integer> pair = wordOccurrencesMap.computeIfAbsent(word, w -> new Pair<>(w, 0));
synchronized(pair) {
pair.setValue(pair.getValue()+1);
}
現(xiàn)在你可以省略你的synchronized(this)塊。
編輯:但是您必須確保當(dāng)?shù)谝粋€(gè)線程調(diào)用pair.setValue() 時(shí),沒有另一個(gè)線程可以調(diào)用pair.getValue(),如注釋所述。
添加回答
舉報(bào)