Kau*_*shi 4 java hashmap concurrenthashmap concurrentmodification
我正在尝试使用故障保护的示例ConcurrentHashMap.
下面是我试过的示例片段..
ConcurrentHashMap<String, String> cMap = new ConcurrentHashMap<String, String>();
cMap.put("1", "Windows Phone");
cMap.put("2", "iPhone");
cMap.put("3", "HTC");
Iterator iterator=cMap.keySet().iterator();
while (iterator.hasNext()) {
System.out.println(cMap.get(iterator.next()));
cMap.put("Samsung", "S5");
}
Run Code Online (Sandbox Code Playgroud)
输出是:
Windows Phone
HTC
iPhone
Run Code Online (Sandbox Code Playgroud)
这是我理解的一个故障保护示例.
但是当我尝试下面的例子时,我得到了不同的输出.
ConcurrentHashMap<String, String> cMap = new ConcurrentHashMap<String, String>();
cMap.put("1", "Windows Phone");
cMap.put("2", "iPhone");
cMap.put("3", "HTC");
Iterator iterator=cMap.keySet().iterator();
while (iterator.hasNext()) {
System.out.println(cMap.get(iterator.next()));
cMap.put("4", "S5");
}
Run Code Online (Sandbox Code Playgroud)
输出是
Windows Phone
HTC
S5
iPhone
Run Code Online (Sandbox Code Playgroud)
上面两个代码片段之间有什么区别.在第二个代码片段中,我添加了cMap.put("4","S5"); 而这正在增加.但是在fisrt片段中,我添加了cMap.put("三星","S5"); 这没有被添加到ConcurrentHashmap.我是否犯了任何错误或者其他可能是这种不同输出的原因.
提前致谢.
Sim*_*nni 13
与非并发hashmap相反,并发映射如果在迭代时添加内容,则不会快速失败.
但是,无法保证迭代器(或get()方法或任何其他读取操作)何时以及是否将看到新添加/删除的元素.
从文档:
Iterators和Enumerations在迭代器/枚举创建时或之后的某个时刻返回反映哈希表状态的元素
编辑:
连贯的不同结果背后的原因在于ConcurrentHashMap如何组织段并对它们进行迭代.
根据密钥的哈希值将密钥映射到不同的段:
"1" -> 15 "2" -> 0 "3" -> 6 "4" -> 5 "Samsung" -> 7
当调用迭代器时,它会迭代从最后到第一个的段.
因此,在0时刻,迭代器从段15开始,在那里找到键"1"="Windows phone",它首先进入输出.
然后,由于迭代器内部实现,它到达下一个元素,即段6的"3"="HTC".
此时插入"S5"就到位了.如果键是"4",它将进入第5段,如果键是"三星",它将进入第7段.
发送"HTC"到输出后,它搜索下一个元素.
当键为"4"时,它进入段5,找到"4"="S5",并将其发送到输出.
当键是"三星"时,该条目进入第7段,该段已被扫描并被迭代器发现为空,因此它找不到它并直接进入段0以检索"2"="Iphone".
这解释了这种行为.
| 归档时间: |
|
| 查看次数: |
2886 次 |
| 最近记录: |