0

I'm trying to understand occurrence of ConcurrentModificationExceptionin below program.

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);
    }

}

Exception:

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)

My doubt is why ConcurrentHashMap takes care of any new entry in the map at runtime whereas HashMap throws ConcurrentModificationException ?

I'm not able to understand this reason "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.

My understanding says, myMap is pointing to two different objects sequentially, then how this error could happen ? Am I wrong ?

Please help to understand why its happening and reason for that. What is fail-fast as well ?

Thanks

mariuss
  • 1,177
  • 2
  • 14
  • 30
Elena
  • 181
  • 1
  • 11

1 Answers1

0

short answer: when you iterate a collection you must not change it. you can just call remove method of iterator. so below line( in hashmap case) is the reason of exception.

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

More explain:

HashMap is fail-fast

javadoc of HashMap says:

The iterators returned by all of this class's "collection view methods" are fail-fast

what is fail-fast? this link says:

Fail fast or fail early is a software engineering concept that tries to prevent complex problems from happening by stopping execution as soon as something that shouldn't happen, well, happens.

ConcurrentHashMap is weakly consistent(or fail-safe)

javadoc of keyset method in ConncurentHashMap says:

The view's iterators and spliterators are weakly consistent

what is weakly consisten? this link says:

they may proceed concurrently with other operations they will never throw ConcurrentModificationException they are guaranteed to traverse elements as they existed upon construction exactly once, and may (but are not guaranteed to) reflect any modifications subsequent to construction.

Mehran Mastcheshmi
  • 785
  • 1
  • 4
  • 12