Tutorial

ConcurrentHashMap in Java

Published on August 3, 2022
Default avatar

By Pankaj

ConcurrentHashMap in Java

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Java ConcurrentHashMap class is part of the Concurrency Collection Classes. It’s a hash table implementation, which supports concurrent retrieval and updates. It’s used in a multi-threaded environment to avoid ConcurrentModificationException.

ConcurrentHashMap

If we try to modify the collection while iterating over it, we get ConcurrentModificationException. Java 1.5 introduced Concurrent classes in the java.util.concurrent package to overcome this scenario. ConcurrentHashMap is the Map implementation that allows us to modify the Map while iteration. The ConcurrentHashMap operations are thread-safe. ConcurrentHashMap doesn’t allow null for keys and values.

Java ConcurrentHashMap Example

The ConcurrentHashMap class is similar to HashMap, except that it’s thread-safe and allows modification while iteration.

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)

It’s clear from the output that ConcurrentHashMap takes care of the new entry in the map while iteration whereas HashMap throws ConcurrentModificationException. Let’s look at the exception stack trace closely. The following statement has thrown Exception.

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 the exception.

How does iterator know about the modification in the Collection?

We have taken the set of keys from HashMap 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;

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

The output with the above code:

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}

What happens if the key value is modified?

What if we don’t add a new entry but update the existing key-value pair? Will it throw exception? Let’s change the code in the original program and check it out.

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

There won’t be any exception because the collection is modified but its structure remains the same.

Further Reading

Did you notice those angle brackets while creating our collection object and Iterator? It’s called generics 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. You should also read Java Collections Interview Questions and Iterator Design Pattern in Java.

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

Reference: API Doc

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Pankaj

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
December 27, 2019

Reached many students.Great content.

- vellaivaranan

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    February 12, 2019

    everybody comes here only everytime before the interview :)

    - haider raza

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      August 21, 2018

      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.

      - Krishna

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        August 21, 2018

        Here, where you are using count variable.

        - Krishna

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          February 9, 2018

          Really Excellent Explain

          - Bipil Raut

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            November 24, 2017

            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}

            - Anand Maheshwari

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              July 12, 2017

              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

              - Vikas Kumar

                JournalDev
                DigitalOcean Employee
                DigitalOcean Employee badge
                April 12, 2017

                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

                - Tejas

                  JournalDev
                  DigitalOcean Employee
                  DigitalOcean Employee badge
                  February 9, 2017

                  Excellent example

                  - narayana

                    JournalDev
                    DigitalOcean Employee
                    DigitalOcean Employee badge
                    October 14, 2016

                    Great example ,nice explaination,Thanks for sharing.

                    - Rupa

                      Try DigitalOcean for free

                      Click below to sign up and get $200 of credit to try our products over 60 days!

                      Sign up

                      Join the Tech Talk
                      Success! Thank you! Please check your email for further details.

                      Please complete your information!

                      Get our biweekly newsletter

                      Sign up for Infrastructure as a Newsletter.

                      Hollie's Hub for Good

                      Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

                      Become a contributor

                      Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

                      Welcome to the developer cloud

                      DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

                      Learn more
                      DigitalOcean Cloud Control Panel