我正试图了解下面程序中ConcurrentModificationException
的出现。
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ConcurentHashMapExample {
public static void main(String[] args) {
Map<String,String> myMap = new ConcurrentHashMap<String,String>();
myMap.put("1", "1");
myMap.put("2", "1");
myMap.put("3", "1");
myMap.put("4", "1");
myMap.put("5", "1");
myMap.put("6", "1");
System.out.println("ConcurrentHashMap before iterator: "+myMap);
Iterator<String> it = myMap.keySet().iterator();
while(it.hasNext()){
String key = it.next();
if(key.equals("3")) myMap.put(key+"new", "new3");
}
System.out.println("ConcurrentHashMap after iterator: "+myMap);
myMap = new HashMap<String,String>();
myMap.put("1", "1");
myMap.put("2", "1");
myMap.put("3", "1");
myMap.put("4", "1");
myMap.put("5", "1");
myMap.put("6", "1");
System.out.println("HashMap before iterator: "+myMap);
Iterator<String> it1 = myMap.keySet().iterator();
while(it1.hasNext()){
String key = it1.next();
if(key.equals("3")) myMap.put(key+"new", "new3");
}
System.out.println("HashMap after iterator: "+myMap);
}
}
例外:
ConcurrentHashMap before iterator: {1=1, 2=1, 3=1, 4=1, 5=1, 6=1}
ConcurrentHashMap after iterator: {1=1, 2=1, 3=1, 4=1, 5=1, 3new=new3, 6=1}
HashMap before iterator: {1=1, 2=1, 3=1, 4=1, 5=1, 6=1}
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(Unknown Source)
at java.util.HashMap$KeyIterator.next(Unknown Source)
at ConcurentHashMapExample.main(ConcurentHashMapExample.java:39)
我的疑问是,为什么ConcurrentHashMap
在运行时会处理映射中的任何新条目,而HashMap
会抛出ConcurrentModificationException
吗?
我无法理解这个原因"Iterator on Collection objects are fail-fast i.e any modification in the structure or the number of entry in the collection object will trigger this exception thrown by iterator.
我的理解是,myMap
依次指向两个不同的对象,那么该错误如何发生?我错了吗?
请帮助了解其发生原因以及原因。什么是快速失败?
谢谢
答案 0 :(得分:0)
简短答案:当您迭代集合时,不得更改它。您可以只调用迭代器的remove方法。所以下面的行(在hashmap情况下)是异常的原因。
if(key.equals("3")) myMap.put(key+"new", "new3")
更多说明:
HashMap快速失败
HashMap的javadoc说:
此类的所有“集合视图方法”返回的迭代器都是快速失败的
什么是快速失败? link说:
快速失败或早期失败是一种尝试的软件工程概念 通过停止执行来防止复杂问题的发生 一旦不该发生的事情就发生了。
ConcurrentHashMap的一致性很弱(或故障安全)
ConncurentHashMap中的键集方法的Javadoc说:
视图的迭代器和分离器是弱一致性的
什么是弱组合? link说:
他们可能会与其他操作同时进行,他们永远不会 抛出ConcurrentModificationException保证它们遍历 元素在构造中仅存在一次,并且可能(但 不能保证)反映出施工后的任何修改。