我將 main 中的字串串列拆分為 2 個不同的執行緒來映射里面的單詞。
每次執行此代碼時,都會得到不同的映射結果。
要么我有一個很大的邏輯缺陷,要么我缺少關于執行緒和并發集合的東西。
誰能理解為什么會這樣?
串列中添加了 8 個“a”和 6 個“b”。
PS 如果我只使用一個執行緒,這不會發生!
編輯 1
將 map.put() 更改為 map.merge(word, 1, Integer::sum),仍然不起作用
編輯 2
以下解決方案我沒有使用 if/else,僅合并并且按預期作業。
public class MyThread extends Thread {
private List<String> list;
private final ConcurrentHashMap<String, Integer> map;
public MyThread(ConcurrentHashMap<String, Integer> map, List<String> list) {
this.map = map;
this.list = list;
}
@Override
public void run() {
for (String word : list){
map.merge(word, 1, Integer::sum);
}
}
public ConcurrentHashMap<String, Integer> getMap() {
return map;
}
}
public static void main(String[] args) throws InterruptedException {
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
List<String> list = new ArrayList<>();
list.add("a");list.add("a");list.add("a");list.add("a");list.add("b");list.add("b");list.add("b");
list.add("a");list.add("a");list.add("a");list.add("a");list.add("b");list.add("b");list.add("b");
MyThread[] ts = new MyThread[2];
int start = 0;
int end = list.size()/2;
for (int i = 0; i < 2; i ){
ts[i] = new MyThread(map,new ArrayList<>(list.subList(start, end)));
ts[i].start();
start = end;
end = list.size();
}
for (int i = 0; i < 2; i ){
ts[i].join();
}
for(String word : map.keySet()){
System.out.println("Key = " word ". Value = " map.get(word));
}
}
uj5u.com熱心網友回復:
第一件事情-你應該使用map.containsKey(word)來代替map.contains(word)。
一些運行后關于不同的結果。呼叫containsKey()和merge()方法時沒有原子代碼。它們在原子上是分開的,但不是原子上的。解決方案只是更改您的代碼并僅呼叫merge()原子。你根本不需要if-else部分。
@Override
public void run() {
for (String word : list) {
map.merge(word, 1, Integer::sum);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/354216.html
下一篇:函式代替靜態實用方法
