ConcurrentHashMap

Key points :

  • The underlying data structure is Hashtable
  • ConcurrentHashMap allows concurrent read(any number of read) and thread-safe update operations
  • To perform read operation thread won’t require any lock
  • To perform write operation thread requires lock but it is lock of only a part of map(Segment lock/bucket lock) instead of total map
  • Concurrent update achieved by internally dividing map into smaller portions(Segments), which is defined by concurrency level.
  • The default concurrency level is 16
  • Any number of reads are allowed but 16 update operations at a time by default.
  • null is not allowed for both keys and values. (Disadvantage)
  • While one thread iterating over CurrentHashMap other thread can perform an update and it will not throw ConcurrentModificationException.
  • Reads are not blocked (it is implemented as reading volatile variables). Writes could block each other if they write in the same segment.(Reference StackOverflow)

Constructors of ConcurrentHashmap

  • ConcurrentHashMap chm = new ConcurrentHashMap();
    • default initial capacity 16, default fill ratio 0.75, and default concurrency level 16
  • ConcurrentHashMap chm = new ConcurrentHashMap(int initialCapacity);
    • default fill ratio 0.75, and default concurrency level 16
  • ConcurrentHashMap chm = new ConcurrentHashMap(int initialCapacity, float fillRatio);
    • default concurrency level 16
  • ConcurrentHashMap chm = new ConcurrentHashMap(int initialCapacity, float fillRatio, int concurrencyLevel);
  • ConcurrentHashMap chm = new ConcurrentHashMap(Map m);

Example 1 of concurrentHashMap methods :

	public static void main(String[] args) {
		ConcurrentHashMap<Integer,String> m = new ConcurrentHashMap<Integer, String>();
		m.put(101, "A");
		m.put(102, "B");
		m.putIfAbsent(103, "C");
		m.putIfAbsent(101,"D");
		m.remove(101, "D");
		m.replace(102, "B", "E");
		System.out.println(m); //{101=A, 102=E, 103=C}
	}

Example 2 of concurrentHashMap
– If you put HashMap you will get concurrent modification exception
– But if you use ConcurrentHashMap you will not get this exception

package com.demo;

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

public class CHMDemo extends Thread{
//		static Map<Integer,String> tempMap = new HashMap<>();
		static Map<Integer,String> tempMap = new ConcurrentHashMap<>();
	    public void run() {
	        try {
	            TimeUnit.SECONDS.sleep(4);
	            tempMap.put(222, "D");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
     
    public static void main(String[] args) {
    	tempMap.put(101, "A");
    	tempMap.put(102, "B");
    	tempMap.put(103, "C");
    	tempMap.put(104, "C");
    	tempMap.put(105, "C");
    	tempMap.put(106, "C");
    	tempMap.put(107, "C");
    	tempMap.put(108, "C");
    	tempMap.put(109, "C");
    	
    	CHMDemo t = new CHMDemo();
        t.start();
        Iterator<Integer> itr = tempMap.keySet().iterator();
        while(itr.hasNext()) {
            try {
                TimeUnit.SECONDS.sleep(1);
                Integer i = itr.next();
                System.out.println("Key : "+i+" Value : "+tempMap.get(i));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

Note : In above program there is not guarantee that the element added to the map by the new thread will be displayed by iterator since it is only a single directional cursor and there is no guarantee that the iterator has passed that bucket location or not

Good Read

Reference :

Leave a Comment