【问题标题】:ConcurrentModificationException: Exception in thread [duplicate]ConcurrentModificationException:线程中的异常[重复]
【发布时间】:2019-03-12 07:04:34
【问题描述】:

我试图了解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 依次指向两个不同的对象,那么这个错误怎么会发生呢?我错了吗?

请帮助理解它发生的原因和原因。什么是快速失败?

谢谢

【问题讨论】:

    标签: java collections hashmap iterator concurrenthashmap


    【解决方案1】:

    简短的回答:当你迭代一个集合时,你不能改变它。你可以调用迭代器的 remove 方法。所以下面的行(在 hashmap 的情况下)是异常的原因。

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

    更多解释:

    HashMap 是快速失败的

    HashMap 的 javadoc 说:

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

    什么是快速失败?这个link 说:

    快速失败或过早失败是一个软件工程概念,它尝试 通过停止执行来防止复杂问题的发生 不应该发生的事情,马上发生。

    ConcurrentHashMap 弱一致(或故障安全)

    ConncurentHashMap 中 keyset 方法的 javadoc 说:

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

    什么是弱一致性?这个link 说:

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

    【讨论】:

      猜你喜欢
      • 2017-02-10
      • 2014-08-24
      • 2015-08-07
      • 2017-01-11
      • 2013-12-18
      • 2011-07-07
      • 2012-08-25
      • 2012-12-09
      • 1970-01-01
      相关资源
      最近更新 更多