ConcurrentModificationException:线程

时间:2018-10-07 11:50:27

标签: java collections hashmap iterator concurrenthashmap

我正试图了解下面程序中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依次指向两个不同的对象,那么该错误如何发生?我错了吗?

请帮助了解其发生原因以及原因。什么是快速失败?

谢谢

1 个答案:

答案 0 :(得分:0)

简短答案:当您迭代集合时,不得更改它。您可以只调用迭代器的remove方法。所以下面的行(在hashmap情况下)是异常的原因。

if(key.equals("3")) myMap.put(key+"new", "new3")

更多说明:

HashMap快速失败

HashMap的javadoc说:

  

此类的所有“集合视图方法”返回的迭代器都是快速失败的

什么是快速失败? link说:

  

快速失败或早期失败是一种尝试的软件工程概念   通过停止执行来防止复杂问题的发生   一旦不该发生的事情就发生了。

ConcurrentHashMap的一致性很弱(或故障安全)

ConncurentHashMap中的键集方法的Javadoc说:

  

视图的迭代器和分离器是弱一致性的

什么是弱组合? link说:

  

他们可能会与其他操作同时进行,他们永远不会   抛出ConcurrentModificationException保证它们遍历   元素在构造中仅存在一次,并且可能(但   不能保证)反映出施工后的任何修改。