簡體   English   中英

同時向HashMap中添加元素

[英]Adding elements to an HashMap concurrently

如果我迭代標准HashMap並嘗試在迭代時向其添加元素,則會得到ConcurrentModificationException

所以我嘗試了一個HashMap允許並發添加:

ConcurrentHashMap<String, Integer> cMap = new ConcurrentHashMap<>();
cMap.put("one", 1);
cMap.forEach((key, value) -> cMap.put(key + key, value + value));
System.out.println(cMap);

但是,生成的地圖有點奇怪:

 {oneoneoneoneoneoneoneone=8, one=1, oneone=2, oneoneoneone=4}

並且如果將密鑰更改為zx( cMap.put("zx", 1) ),則結果為:

{zxzx=2, zx=1}

問題:

1)為什么會這樣? 兩個並發操作(迭代和添加)不應沖突。

2)如何解決不一致問題?

與Collections相反,當在迭代String的char時更改String時,不會遇到此問題:

        String str = scanner.next();
        for (int i = 1; i < str.length(); i++) {
            if (str.charAt(i) == str.charAt(i-1)) {
                str = str.substring(0, i-1) + str.substring(i+1);
                i = 0;
            }
        }
        if (str.length() == 0) {
            System.out.println("Empty String");
        } else {
            System.out.println (str);
        }
    }

請注意,在上面的循環中,實際上並未更改源String,而是將其重新分配,因為String是不可變的,無法修改

上面的代碼可以正常工作。 這是字符串為什么是線程安全的示例嗎?

歸結為新元素添加到哪個哈希存儲桶。 在第一個示例中,新元素被添加到比您正在使用的元素更高的哈希存儲桶中,並且迭代器尚未到達。 在第二個示例中,新元素被添加到迭代器已讀取的較早的哈希存儲桶中。

您應該非常警惕在迭代過程中修改集合。 對於您而言,最好將新條目添加到新地圖中,然后將它們合並在一起。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM