Need for Concurrent Collections:

1. Tradition Collection Object (like ArrayList, HashMap etc) can be accessed by Multiple Threads simultaneously and there may be a chance of data inconsistency problems and hence these are not Thread safe.
2. Already existing Thread safe Collections (vector, Hashtable, synchronizedList(), synchronizedSet(), synchronizedMap() ) performance wise not up to the mark.
3. Because for every operation even for read operation also total collection will be loaded by only one Thread at a time and it increases waiting time of Threads.


import java.util.*;
class MyThread extends Thread{
    static ArrayList l = new ArrayList();
    public void run(){
        try{
            Thread.sleep(2000);
        }
        catch(InterruptedException e){
            System.out.println("Child Thread updating List");
            l.add("D");
        }
    }
    public static void main(String[] argsthrows InterruptedException{
        l.add("A");
        l.add("B");
        l.add("C");
        MyThread t = new MyThread();
        t.start();
        Iterator itr = l.iterator();
        while(itr.hasNext()){
            String s1 = (String)itr.next();
            System.out.println("Main Thread iterating List and Current Object is " + s1);
            Thread.sleep(3000);
        }
        System.out.println(l);
    }
}

Output:
Main Thread iterating List and Current Object is A
Main Thread iterating List and Current Object is B
Main Thread iterating List and Current Object is C
[A, B, C]

1. Another Big problem with Traditional Collections is while one Thread iterating Collection, the other Threads are not allowed to modify Collection object simultaneously if we are trying to modify then we will get ConcurrentModificationException.
2. Hence these Traditional Collection objects are not suitable for scalable multi-threaded applications.
3. To overcome these problems SUN people introduced Concurrent Collections in 1.5 version.


Differences between Traditional and Concurrent Collections:

1. Concurrent Collections are always Thread safe compared to Traditional Collections.
2. When compared with Traditional Thread safe Collections performance is more because of different locking mechanism.
3. While one Thread interacting Collection the other Threads are allowed to modify Collection in safe manner.

Hence Concurrent Collections never throw ConcurrentModificationException

The important Concurrent classes are
1. ConcurrentHashMap
2. CopyOnWriteArrayList
3. CopyOnWriteArraySet


ConcurrentMap(I):

It defines the following 3 specific methods:

1. Object putIfAbsent(Object key, Object value)

to add entry to the Map if the specified key is not already available.

if(!map.containsKey(key)){
    map.put(key, value);
}
else{
    return map.get(key);
}
put()

if the key is already available, old value will be replaced with new value and returns old value.

putIfAbsent()

If the key is already present then entry won’t be added and returns old associated value. If the key is not available then only entry will be added.

//TraditionalMap
m.put(101"kalyan");
m.put(101"kadali");
System.out.println(m); //{101 = kadali}
//ConcurrentMap
m.putIfAbsent(101"kalyan");
m.putIfAbsent(101"kadali");
System.out.println(m); //{101 = kalyan}
import java.util.concurrent.ConcurrentHashMap;
class Demo{
    public static void main(String[] args){
        ConcurrentHashMap m = new ConcurrentHashMap();
        m.put(101"kalyan");
        m.put(101"kadali");
        System.out.println(m); //{101 = kadali}
        m.putIfAbsent(101"sai");
        System.out.println(m); //{101 = kadali}
    }
}

Output:
{101=kadali}
{101=kadali}


2. boolean remove(Object key, Object value)

removes the entry if the key associated with specified value only.

if(!map.containsKey(key) && map.get(key).equals(value)){
    map.remove(key);
    return true;
}
else{
    return false;
}
//TradiitonalMap
m.put(101"kalyan");
m.remove(101);
System.out.println(m); //{}
//ConcurrentMap
m.put(101"kalyan");
m.remove(101"kadali");
System.out.println(m); //{101 = kalyan}
m.remove(101"kalyan");
System.out.println(m); //{}
import java.util.concurrent.ConcurrentHashMap;
class Demo{
    public static void main(String[] args){
        ConcurrentHashMap m = new ConcurrentHashMap();
        m.put(101"kalyan");
        m.remove(101"kadali"); //value not matched with key so not removed
        System.out.println(m); //{101 = kadali}
        m.remove(101"kalyan");
        System.out.println(m); //{}
    }
}

Output:
{101=kalyan}
{}

3. boolean replace(Object key, Object oldValue, Object newValue)

If old value matches then replace with new value.

if(!map.containsKey(key) && map.get(key).equals(oldValue)){
    map.put(key, newValue);
    return true;
}
else{
    return false;
}
import java.util.concurrent.ConcurrentHashMap;
class Demo{
    public static void main(String[] args){
        ConcurrentHashMap m = new ConcurrentHashMap();
        m.put(101"kalyan");
        m.replace(101"kadali""sai");
        System.out.println(m); //{101 = kalyan}
        m.replace(101"kalyan""sai");
        System.out.println(m); //{101 = sai}
    }
}

Output:
{101=kalyan}
{101=sai}


ConcurrentHashMap:

ConcurrentHashMap

1. Underlying Data Structure is Hashtable.
2. ConcurrentHashMap allows Concurrent read and Thread safe update operations.
3. To perform read operation Thread won’t require any lock. But to perform update operation Thread requires lock but it is the lock of only a particular part of Map (Bucket Level Lock).
4. Instead of whole Map Concurrent update achieved by internally dividing Map into smaller portion which is defined by Concurrent level.
5. The default Concurrency level is 16.
That is ConcurrentHashMap allows simultaneous read operation and simultaneously 16 write(update) operations.
6. Null is not allowed for both keys and values.
7. While one Thread iterating the other Thread can perform Update operation and ConcurrentHashMap never throw ConcurrentModificationException.

Constructors:

public ConcurrentHashMap()

creates an empty ConcurrentHashMap with default initial capacity is 16 and default fill ratio is 0.75 and default Concurrency level is 16.

public ConcurrentHashMap(int initalCapacity)
public ConcurrentHashMap(int initalCapacity, float fillRatio)
public ConcurrentHashMap(int initalCapacity, float fillRatio, int concurrencyLevel)
public ConcurrentHashMap(Map m)
import java.util.concurrent.ConcurrentHashMap;
class ConcurrentHashMapDemo{
    public static void main(String[] args){
        ConcurrentHashMap m = new ConcurrentHashMap();
        m.put(101"A");
        m.put(101"B");
        m.putIfAbsent(103"C");
        m.putIfAbsent(101"D");
        m.remove(101"D");
        m.replace(102"B""E");
        System.out.println(m);
     }
}

Output:
{101=B, 103=C}


import java.util.*;
class MyThread extends Thread{
    static ConcurrentHashMap l = new ConcurrentHashMap();
    public void run(){
        try{
            Thread.sleep(2000);
        }
        catch(InterruptedException e){
            System.out.println("Child Thread updating Map");
            m.put("C");
        }
    }
    public static void main(String[] argsthrows InterruptedException{
        m.put(101"A");
        m.put(102"B");
        MyThread t = new MyThread();
        t.start();
        Set s = m.keySet();
        Iterator itr = s.iterator();
        while(itr.hasNext()){
            Integer i1 = (Integer)itr.next();
            System.out.println("Main Thread iterating and Current Entry is " + i1 + " ------" + m.get(i1));
            Thread.sleep(3000);
        }
        System.out.println(m);
    }
}

Output:
Main Thread iterating and Current Entry is 101 ------A
Main Thread iterating and Current Entry is 102 ------B
{101=A, 102=B}


Differences between HashMap and ConcurentHashMap:

HashMap ConcurentHashMap
It is not Thread safe It is Thread safe
Relatively performance is high because Threads are not required to wait to operate on HashMap. Relatively performance is low because sometimes Threads are required to wait to operate on ConcurrentHashMap.
While one Thread iterating HashMap the other Threads are not allowed to modify Map Objects otherwise we will get runtime exception saying ConcurrentModificationException. While one Thread iterating ConcurrentHashMap the other Threads are allowed to modify Map Objects in safe manner and it won’t throw ConcurrentModificationException.
Iterator of HashMap is fail-fast and it throws ConcurrentModificationException. Iterator of ConcurrentHashMap is fail-safe and it won’t throws ConcurrentModificationException.
Null is allowed for both keys and values Null is not allowed for both keys and values. Otherwise, we will get NullPointerException
Introduced in 1.2V Introduced in 1.5V

Differences between ConcurrentHashMap, synchronizedMap() and Hashtable

ConcurrentHashMap synchronizedMap Hashtable
we will get Thread safety without locking total Map object just with Bucket Level Lock. we will get Thread safety by locking whole Map object. we will get Thread safety by locking whole Map object.
At a time, multiple Threads are allowed to operate on Map object in safe manner At a time only one Thread is allowed to perform operation on Map object. At a time only one Thread is allowed to operate on Map object.
Read operation can be performed without lock but write operation can be performed with Bucket Level Lock. Every read and write operations require total Map Object lock. Every read and write operations require total Map Object lock.
While one Thread iterating Map object, the other Threads are allowed to modify Map and we won’t get ConcurrentModificationException While one Thread iterating Map object, the other Threads are not allowed to modify Map and we will get ConcurrentModificationException While one Thread iterating Map object, the other Threads are not allowed to modify Map and we will get ConcurrentModificationException
Iterator of ConcurrentHashMap is fail-safe and won’t raise ConcurrentModificationException. Iterator of synchronizedMap() is fail-fast and will raise ConcurrentModificationException. Iterator of Hashtable is fail-fast and will raise ConcurrentModificationException.
Null is not allowed for both keys and values Null is allowed for both keys and values Null is not allowed for both keys and values
Introduced in 1.5 version Introduced in 1.2 version Introduced in 1.0 version

CopyOnWriteArrayList:

CopyOnWriteArrayList

It is a Thread safe version of ArrayList as the name indicates CopyOnWriteArrayList creates a cloned copy of underlying ArrayList for every update operation at certain point both will synchronize automatically which is taken care by JVM internally.

1. As update operation will be performed on cloned copy there is no effect for the Threads which performs read operation.
2. It is costly to use because for every update operation a cloned copy will be created. Hence CopyOnWriteArrayList is the best choice if several read operations and a smaller number of write operations are required to perform.
3. Insertion order is preserved.
4. Duplicate objects are allowed.
5. Heterogeneous objects are allowed.
6. Null insertion is possible.
7. It implements Serializable, Cloneable and RandomAccesss interfaces.
8. While one Thread iterating CopyOnWriteArrayList, the other Threads are allowed to modify and wont get ConcurrentModificationException i.e., iterator is fail-safe.
9. Iterator of ArrayList can perform remove operation but iterator of CopyOnWriteArrayList can’t perform remove operation. Otherwise, we will get runtime exception saying UnsupportedOperationException.


Constructors:

public CopyOnWriteArrayList()
public CopyOnWriteArrayList(Collection c)
public CopyOnWriteArrayList(Object[] a)

CopyOnWriteArrayList specific methods:

1. boolean addIfAbsent(Object o)

the element will be added if and only if List doesn’t contain this element.

CopyOnWriteArrayList l = new CopyOnWriteArrayList();
l.add("A");
l.add("A");
l.addIfAbsent("B");
l.addIfAbsent("B");
System.out.printlln(l); //[A. A, B]

2. int addAllAbsent(Collection c)

the elements of Collection will be added to List if elements are absent and returns number of elements added.

//Program on CopyOnWriteArrayList
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.*;
class CopyOnWriteArrayListDemo{
    public static void main(String[] args){
        ArrayList l = new ArrayList();
        l.add("A");
        l.add("B");
        CopyOnWriteArrayList l1 = new CopyOnWriteArrayList();
        l1.add("A");
        l1.add("C");
        System.out.println(l1); //[A, C]
        l1.addAll(l);
        System.out.println(l1); //[A, C, A, B]
        ArrayList l2 = new ArrayList();
        l2.add("A");
        l2.add("D");
        l1.addAllAbsent(l2);
        System.out.println(l1); //[A, C, A, B, D]
    }
}

//Program on CopyOnWriteArrayList
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.*;
class CopyOnWriteArrayListDemo{
    public static void main(String[] args){
        ArrayList l = new ArrayList();
        l.add("A");
        l.add("B");
        CopyOnWriteArrayList l1 = new CopyOnWriteArrayList();
        l1.addIfAbsent("A");
        l1.addIfAbsent("C");
        l1.addAll(l);
        ArrayList l2 = new ArrayList();
        l2.add("A");
        l2.add("E");
        l1.addAllAbsent(l2);
        System.out.println(l1); //[A, C, A, B, E]
    }
}

//Program on CopyOnWriteArrayList
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.*;
class MyThread extends Thread{
    static CopyOnWriteArrayList l = new CopyOnWriteArrayList();
    public void run(){
        try{
            Thread.sleep(2000);
        }
        catch(InterruptedException e){
            System.out.println("Child Thread updating List");
            l.add("C");
        }
    }
    public static void main(String[] argsthrows InterruptedException{
        l.add("A");
        l.add("B");
        MyThread t = new MyThread();
        t.start();
        Iterator itr = l.iterator();
        while(itr.hasNext()){
            String s= (String)itr.next();
            System.out.println("Main Thread iterating and Current Object is " +s);
            Thread.sleep(3000);
        }
        System.out.println(l);
    }
}

Output:
Main Thread iterating and Current Object is A
Main Thread iterating and Current Object is B
[A, B]

In the above example while main Thread iterating List child Thread is allowed to modify and we won't get any ConcurrentModificationException.
If we replace CopyOnWriteArrayList with ArrayList then we will get ConcurrentModificationException.
Iterator of CopyOnWriteArrayList can’t perform remove operation. Otherwise, we will get runtime exception saying UnsupportedOperationException

//Program on CopyOnWriteArrayList
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.*;
class CopyOnWriteArrayListDemo{
    public static void main(String[] args){
        CopyOnWriteArrayList l = new CopyOnWriteArrayList();
        l.add("A");
        l.add("B");
        l.add("C");
        l.add("D");
        System.out.println(l); //[A, B, C, D]
        Iterator itr = l.iterator();
        while(itr.hasNext()){
            String s = (String)itr.next();
            if(s.equals("D")){
                itr.remove(); //RE:UnsupportedOperationException
            }
        }
        System.out.println(l);
     }
}

Output:
[A, B, C, D]

Exception in thread "main" java.lang.UnsupportedOperationException   at

java.base/java.util.concurrent.CopyOnWriteArrayList$COWIterator.remove(CopyOnWriteArrayList

.java:1124) at CopyOnWriteArrayListDemo.main(CopyOnWriteArrayListDemo.java:15)

If we replace CopyOnWriteArrayList with ArrayList we won’t get any UnsupportedOperationException.
In this case the output is
[A, B, C, D]
[A, B, C]


//Program on CopyOnWriteArrayList
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.Iterator;
class CopyOnWriteArrayListDemo{
    public static void main(String[] args){
        CopyOnWriteArrayList l = new CopyOnWriteArrayList();
        l.add("A");
        l.add("B");
        l.add("C");
        Iterator itr = l.iterator();
        l.add("D");
        while(itr.hasNext()){
            String s = (String)itr.next();
            System.out.println(s);
        }
    }
}

Output:
A
B
C
Reason:
Every update operation will be performed on separate copy. Hence after getting iterator if we are trying to perform any modification to the List it won’t be reflected to the iterator.
In the above program if we replace CopyOnWriteArrayList with ArrayList then we will get runtime Exception saying ConcurrentModificationException


Differences between ArrayList and CopyOnWriteArrayList

ArrayList CopyOnWriteArrayList
It is not Thread safe. It is not Thread safe because every update operation will be performed on separate cloned copy.
While one Thread iterating List object, the other Threads are not allowed to modify List otherwise we will get ConcurrentModificationException While one Thread iterating List object, the other Threads are allowed to modify List in same manner and we won’t get ConcurrentModificationException
Iterator is Fail-Fast. Iterator is Fail-Safe.
Iterator of ArrayList can perform remove operation. Iterator of CopyOnWriteArrayList can’t perform remove operation otherwise we will get runtime exception saying UnsupportedOperationException.
Introduced in 1.2 Version Introduced in 1.5 Version

Differences between CopyOnWriteArrayList, synchronizedList(), and Vector

CopyOnWriteArrayList synchronizedList() Vector
We will get Thread safety because every update operation will be performed on separate cloned copy. We will get Thread safety because at a time List can be accessed by only one Thread at a time. We will get Thread safety because at a time only one Thread is allowed to access Vector object.
At a time, multiple Threads are allowed to access/operate on CopyOnWriteArrayList. At a time only Thread is allowed to perform any operation on List Object At a time only Thread is allowed to operate on Vector Object
While one Thread iterating List object, the other Threads are allowed to modify and we won’t get ConcurrentModificationException. While one Thread iterating, the other Threads are not allowed to modify List. Otherwise, we will get ConcurrentModificationException. While one Thread iterating, the other Threads are not allowed to modify Vector. Otherwise, we will get ConcurrentModificationException.
Iterator is Fail-Safe and won’t raise ConcurrentModificationException Iterator is Fail-Fast and it will raise ConcurrentModificationException Iterator is Fail-Fats and it will raise ConcurrentModificationException
Iterator can’t perform remove operation otherwise we will get UnsupportedOperationException. Iterator can perform remove operation. Iterator can perform remove operation.
Introduced in 1.5 Version Introduced in 1.2 Version Introduced in 1.0 Version

CopyOnWriteArraySet:

CopyOnWriteArraySet

1. It is a Thread safe version of Set as the name indicates CopyOnWriteArraySet.
2. Insertion order is preserved.
3. Duplicate objects are not allowed.
4. Multiple Threads can able to perform read operation simultaneoulsy but for every update operation a separate cloned copy will be created.
5. As for every update operation a separate cloned copy will be created which is costly. Hence if multiple update operation is required then it is not recommended to use CopyOnWriteArraySet.
6. While one Thread iterating Set the other Threads are allowed to modify Set and we won’t get ConcurrentModificationException.
7. Iterator of CopyOnWriteArraySet can perform only read operation and won’t perform remove operation. Otherwise, we will get runtime exception.

Constructors:

public CopyOnWriteArraySet()

creates an empty CopyOnWriteArraySet object

public CopyOnWriteArraySet(Collection c)

creates an empty CopyOnWriteArraySet object which is equivalent to given Collection object.


CopyOnWriteArraySet specific methods:
Whatever methods in Collection and Set interface are the only methods applicable for CopyOnWriteArraySet and there are no special methods.


import java.util.concurrent.*;
class CopyOnWriteArraySetDemo{
    public static void main(String[] args){
        CopyOnWriteArraySet s = new CopyOnWriteArraySet();
        s.add("D");
        s.add("B");
        s.add("C");
        s.add("A");
        s.add(null);
        s.add(10);
        s.add("D");
        System.out.println(s);
    }
}

Output:
[D, B, C, A, null, 10]

Differences between CopyOnWriteArraySet and synchronizedSet()

CopyOnWriteArraySet synchronizedSet()
It is Thread safe because every update operation will be performed on separate cloned copy. It is Thread safe because at a time only one Thread can perform operation.
While one Thread iterating Set, the other Threads are allowed to modify and we won’t get ConcurrentModificationException While one Thread iterating, the other Threads are not allowed to modify Set otherwise we will get ConcurrentModificationException
Iterator is Fail-Safe. Iterator is Fail-Fast.
Iterator can perform only read operation and can’t perform remove operation otherwise we will get runtime exception saying UnsupportedOperationException. Iterator can perform both read and remove operation.
Introduced in 1.5 version Introduced in 1.2 version