ConcurrentHashMap in Java

Filed Under: Java

ConcurrentHashMap in Java is part of concurrent collection classes. If we try to modify the collection structure while iterating over it, we get ConcurrentModificationException. Actually, Java Collection Framework iterator is great example of iterator design pattern implementation.

ConcurrentHashMap

ConcurrentHashMap in Java

Java 1.5 has introduced java.util.concurrent package with Collection classes implementations that allow you to modify your collection objects at runtime.

Java ConcurrentHashMap Example

ConcurrentHashMap is the class that is similar to HashMap but works fine when you try to modify your map at runtime.

Let’s run a sample program to explore this:

ConcurrentHashMapExample.java


package com.journaldev.util;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentHashMapExample {

	public static void main(String[] args) {

		//ConcurrentHashMap
		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);

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

}

Output:


ConcurrentHashMap before iterator: {1=1, 5=1, 6=1, 3=1, 4=1, 2=1}
ConcurrentHashMap after iterator: {1=1, 3new=new3, 5=1, 6=1, 3=1, 4=1, 2=1}
HashMap before iterator: {3=1, 2=1, 1=1, 6=1, 5=1, 4=1}
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
	at java.util.HashMap$KeyIterator.next(HashMap.java:828)
	at com.test.ConcurrentHashMapExample.main(ConcurrentHashMapExample.java:44)

Looking at the output, it’s clear that ConcurrentHashMap takes care of any new entry in the map whereas HashMap throws ConcurrentModificationException.

Let’s look at the exception stack trace closely. The statement that has thrown Exception is:


String key = it1.next();

It means that the new entry got inserted in the HashMap but Iterator is failing. Actually, Iterator on Collection objects is fail-fast i.e any modification in the structure or the number of entries in the collection object will trigger this exception thrown by the iterator.

So How does iterator know that there has been some modification in the HashMap?

We have taken the set of keys from HashMap once and then iterating over it.

HashMap contains a variable to count the number of modifications and iterator use it when you call its next() function to get the next entry.

HashMap.java


/**
     * The number of times this HashMap has been structurally modified
     * Structural modifications are those that change the number of mappings in
     * the HashMap or otherwise modify its internal structure (e.g.,
     * rehash).  This field is used to make iterators on Collection-views of
     * the HashMap fail-fast.  (See ConcurrentModificationException).
     */
    transient volatile int modCount;

Now to prove the above point, let’s change the code a little bit to come out of the iterator loop when we insert the new entry. All we need to do is add a break statement after the put call.


if(key.equals("3")){
	myMap.put(key+"new", "new3");
	break;
}

Now execute the modified code and the output will be:


ConcurrentHashMap before iterator: {1=1, 5=1, 6=1, 3=1, 4=1, 2=1}
ConcurrentHashMap after iterator: {1=1, 3new=new3, 5=1, 6=1, 3=1, 4=1, 2=1}
HashMap before iterator: {3=1, 2=1, 1=1, 6=1, 5=1, 4=1}
HashMap after iterator: {3=1, 2=1, 1=1, 3new=new3, 6=1, 5=1, 4=1}

Finally, what if we won’t add a new entry but update the existing key-value pair. Will it throw exception?

Change the code in the original program and check yourself.


//myMap.put(key+"new", "new3");
myMap.put(key, "new3");

If you get confused (or shocked) with the output, comment below and I will be happy to explain it further.

Did you notice those angle brackets while creating our collection object and Iterator?

It’s called generics in java and it’s very powerful when it comes to type-checking at compile time to remove ClassCastException at runtime. Learn more about generics in Java Generics Example.

Further Reading: Java Collections Interview Questions and Iterator Design Pattern Java.

You can checkout more Java collection examples from our GitHub Repository.

Reference: API Doc

Comments

  1. haider raza says:

    everybody comes here only everytime before the interview 🙂

  2. Krishna says:

    If we are updating existing key value pair,exception will not come. By using break statement inside if loop, ConcurrentModificationException is resolving. How it is happening by inserting simple break.

    1. Bhavya says:

      It is happening as we are breaking out of the while loop which checks for the has next condition and in turn calling the .next function.

  3. Krishna says:

    Here, where you are using count variable.

  4. Bipil Raut says:

    Really Excellent Explain

  5. Not getting output as
    HashMap after iterator: {3=1, 2=1, 1=1, 3new=new3, 6=1, 5=1, 4=1}
    After adding break after put in hashMap.
    it is as HashMap after iterator: {1=1, 2=1, 3=1, 4=1, 5=1, 6=1}

    1. Anand Maheshwari says:

      Sorry, My mistake it is working fine.

      1. Giap says:

        why you did’nt fix it in the post yet? after recognize it as a mistake of you?
        because this can lead to big misunderstanding problem.

  6. Vikas Kumar says:

    Hi ,

    I have checked this example in our eclipse and it was working in HashMap class too .

    public class ConcurrentHashMapExample {

    /**
    * @param args
    */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    try{
    HashMap map = new HashMap();

    map.put(“One”, “I am one”);
    map.put(“Two”,”I am two”);
    System.out.println(“Map is returned in first”+map);

    Iterator itr= map.keySet().iterator();

    while(itr.hasNext()){
    String key=itr.next();

    System.out.println(“Traversing value”+key);
    if(“One”.equals(key))
    map.put(key+”OneOne”, “I am Eleven”);

    System.out.println(“Map is returned in last”+map);
    }
    }
    catch(Exception e){

    e.printStackTrace();
    }

    Output is :

    Map is returned in first{Two=I am two, One=I am one}
    Traversing valueTwo
    Map is returned in last{Two=I am two, One=I am one}
    Traversing valueOne
    Map is returned in last{OneOneOne=I am Eleven, Two=I am two, One=I am one}

    In case of remove the element from hashmap ,It will showing the exception .Kindly correct the logic here

    1. Munesh says:

      You have only 2 member here. As SET doesn’t preserve the order so in iterator loop if key value “One” occurred in 2nd loop. Now you have added put a new member in the Map. It dosen’t throw the exception because after that loop get exit and it.next() method doesn’t get invoke. As Pankaj explained that ConcurrentModificationException arise only when call for method next() after modifying underlying collection.

      Please try with more number of member and check the same again.
      Thanks.

  7. Tejas says:

    Map hm= new ConcurrentHashMap();
    hm.put(“1”,1);
    hm.put(“2”,2);
    hm.put(“3”,3);
    System.out.println(hm);
    Iterator it = hm.keySet().iterator();

    while(it.hasNext()){
    String key = it.next();
    if(key.equals(“3”))
    hm.put(“3”,4);
    }
    System.out.println(hm);
    System.out.println(“+++++++++++++++++++++++++++++++++++”);
    hm= new HashMap();
    hm.put(“1”,1);
    hm.put(“2”,2);
    hm.put(“3”,3);
    System.out.println(hm);
    Iterator it1 = hm.keySet().iterator();

    while(it.hasNext()){
    String key = it1.next();
    if(key.equals(“3”))
    hm.put(“3”,4);
    }
    System.out.println(hm);

    O/P is
    //concurrent hash map
    {1=1, 2=2, 3=3}
    {1=1, 2=2, 3=4}
    +++++++++++++++++++++++++++++++++++
    //hashmap
    {1=1, 2=2, 3=3}
    {1=1, 2=2, 3=3}

    *Note :- I am using java 8 . is cocncurrent HashpMap example is handeled

  8. narayana says:

    Excellent example

  9. Rupa says:

    Great example ,nice explaination,Thanks for sharing.

  10. Anil Gupta From Sidhi Mp says:

    really awesome

    1. Anil Gupta From Sidhi Mp says:

      thanks for giving this type of deeply knowledge ,

  11. mr_rookie says:

    every time when get a iterator .the operation underlying is :
    public Iterator iterator() {
    return new Itr();
    }
    private class Itr implements Iterator {

    int expectedModCount = modCount;
    ……
    }

    then every mutative operation , thr modcount will be modCount++;
    that’s why when modCount changed ,but expectedModCount was initialized when iterator(),and not changed after.
    if (modCount != expectedModCount)
    throw new ConcurrentModificationException();

  12. husenbadshah goundi says:

    greate example …..superb

  13. Chandrasekhar G says:

    Really this tutorial is awesome.

    Thanks for sharing this.

    Regards,
    Chandu.

  14. Ram says:

    Excellent example about concurenthashmap and concurentmodified exception

  15. NARAYANA says:

    Really helpfull,while attending the inrerviews…It is good !

  16. sunil says:

    Its really good explanation……Thanks…

  17. Ramakrisha says:

    HI

    Very good explantion,its very helpfull to me.

    Thanks

  18. nawaz says:

    i had gone through so many web sites, but no one has given clear definition, but finally i got complete clarity on this point. thanks brother.

  19. Ganesh Rashinker says:

    The above example is good. I have tried to explain the same using multiple threads trying to add data to HashMap.

    http://www.javavisited.com/2014/04/internal-working-of-hashmap_15.html

    and

    http://www.javavisited.com/2014/04/internal-working-of-concurrenthashmap.html

    Please check this website for a demo of what I have mentioned above. Please correct me if my understanding is wrong somewhere.

  20. nikhil says:

    if u are breaking from while when key is 3 then how could it print the remaining values in while loop

    if(key.equals(“3″)){
    myMap.put(key+”new”, “new3”);
    break;
    }

    ConcurrentHashMap before iterator: {1=1, 5=1, 6=1, 3=1, 4=1, 2=1}
    ConcurrentHashMap after iterator: {1=1, 3new=new3, 5=1, 6=1, 3=1, 4=1, 2=1}
    HashMap before iterator: {3=1, 2=1, 1=1, 6=1, 5=1, 4=1}
    HashMap after iterator: {3=1, 2=1, 1=1, 3new=new3, 6=1, 5=1, 4=1}

    The output should be

    ConcurrentHashMap before iterator: {1=1, 5=1, 6=1, 3=1, 4=1, 2=1}
    ConcurrentHashMap after iterator: {1=1, 3new=new3, 5=1, 6=1, 3=1, 4=1, 2=1}
    HashMap before iterator: {3=1, 2=1, 1=1, 6=1, 5=1, 4=1}
    HashMap after iterator: {3=1, 2=1, 1=1, 3new=new3}

    Please clarify

    1. prakash says:

      If you observe carefully he is not displaying value in while loop…
      print is last statement….

  21. Ankit Tripathi says:

    Nicely compiled article. Understood the concept quickly.
    Thank you.

  22. Binh Thanh Nguyen says:

    Thanks, nice post

  23. Devendra says:

    Nicely explained. can you please tell why there is no exception when we are try to change the value but not key.

    //myMap.put(key+”new”, “new3”);
    myMap.put(key, “new3”);

    do we have seperate “modCount” for key and value in map.

    but how it is getting a updated value?

    1. Pankaj says:

      modCount is for key only, since we are not changing the structure of the map the exception is not thrown.

      You are seeing updates value because we are printing the HashMap and not the iterator values.

      1. arif khan says:

        This is the nice tutorial..100/100

  24. Nazeer Khan says:

    For the key “4” :
    while(it1.hasNext()){
    String key = it1.next();
    if(key.equals(“4″)){
    myMap.put(key+”new”, “new4”);
    }
    }

    Output:
    Got no ConcurrentModificationException occured…..
    HashMap before iterator: {3=1, 2=1, 1=1, 6=1, 5=1, 4=1}
    HashMap after iterator: {3=1, 2=1, 1=1, 4new=new4, 6=1, 5=1, 4=1}

    How???

    1. Hi, I am getting the same issue. We are getting error with 3, but not with 4.
      Could you please explain? Why?

      1. I think I got the answer. The issue here is, the key=”4″ is in the last in Hash Map
        HashMap before iterator: {3=1, 2=1, 1=1, 6=1, 5=1, 4=1}

        So, after comparing with “4”, and adding a new key-Value pair “4new”=”new4”, its done with the processing of iterator. As the error is thrown in next call to iterator.next(), so in this case, we are not getting any error. You can check in all other cases you will get the error.

        Please correct me, if my understanding is incorrect.

        1. Abhishek Sunandan says:

          We can have a better understanding if we Use Integer as keys

          //HashMap
          Map myMap1 = new HashMap();
          myMap1.put(1, “1”);
          myMap1.put(2, “1”);
          myMap1.put(3, “1”);
          myMap1.put(4, “1”);
          myMap1.put(5, “1”);
          myMap1.put(6, “1”);
          System.out.println(“HashMap before iterator: “+myMap1);
          Iterator it1 = myMap1.keySet().iterator();

          while(it1.hasNext()){
          Integer key = it1.next();
          if(key.equals(6)) {myMap1.put(7, “new3”);

          }
          }
          System.out.println(“HashMap after iterator: “+myMap1);

          1. Rahul says:

            You can get the “ConcurrentModificationException” when your HashMap, value parameter is of type String.

  25. Sravanthi says:

    I have added code to remove one item from map. the item is removed from map. But when its iterating it is printing the key and with value as null. Does that mean iterator has that key even though map does not have it? Does iterator will have a copy of keys?
    Below is modified code:
    while(it.hasNext()){
    String key = it.next();
    System.out.println(“Key “+key+”value: “+myMap.get(key));
    if(key.equals(“3″)) {
    myMap.put(key+”new”, “new3”);
    myMap.remove(“4”);
    System.out.println(“while iterating: “+myMap);
    }
    }
    System.out.println(“ConcurrentHashMap after iterator: “+myMap);

    ouput is:
    ConcurrentHashMap before iterator: {1=1, 5=1, 6=1, 3=1, 4=1, 2=1}
    Key 1 value: 1
    Key 5 value: 1
    Key 6 value: 1
    Key 3 value: 1
    while iterating: {1=1, 3new=new3, 5=1, 6=1, 3=1, 2=1}
    Key 4 value: null
    Key 2 value: 1
    ConcurrentHashMap after iterator: {1=1, 3new=new3, 5=1, 6=1, 3=1, 2=1}

    1. Pankaj says:

      This is the expected behavior, when you get the iterator from Map then it has all the keys including “4”, now when you remove it, its removed from the HashMap but not from the iterator that you have already got, so its returning NULL.

      1. Sravanthi says:

        Thanks for the quick answer.
        So Iterator has separate memory with key copies?

      2. Ramana Reddy says:

        i have one doubt in this ….
        when ever we remove one value it is removed from HashMap
        but not Iteratior k fine…
        but we are printing only HashMap object on console
        even though why that Null values came for removed object…………………………..

  26. Rajeev says:

    Excellent! Clears the concept and the usage of ConcurrentHashMap Thanks

  27. Ashok singh says:

    defnetly we get confused about Output. Can you Explain more reagarding the above Program…When we adding the element first time it provides an Exception..But When you have Written “Map.put(key, “new3″);” this line it doesnt provide any error.Explain it in better way….

    1. Pankaj says:

      If you use myMap.put(key, “new3”); its actually modifying key value, so there is no structural modification in the HashMap.
      Output will be:
      ConcurrentHashMap before iterator: {1=1, 5=1, 6=1, 3=1, 4=1, 2=1}
      ConcurrentHashMap after iterator: {1=1, 3new=new3, 5=1, 6=1, 3=1, 4=1, 2=1}
      HashMap before iterator: {3=1, 2=1, 1=1, 6=1, 5=1, 4=1}
      HashMap after iterator: {3=new3, 2=1, 1=1, 6=1, 5=1, 4=1}

  28. Khalid says:

    Odd behaviour, the result of the last modification comes out as

    HashMap after iterator: {3=new3, 2=1, 1=1, 6=1, 5=1, 4=1}

  29. internet says:

    As a website resource for companies and engineering enthusiasts to comply with the newest and greatest breakthroughs in Unified Communications, IP Telephony, Hosted Communications and VoIP.

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages