ArrayList is not synchronized. That means sharing an instance of ArrayList among many threads where those threads are modifying (by adding or removing the values) the collection may result in unpredictable behavior.A thread-safe variant of ArrayList in which all mutative operations (e.g. add, set, remove..) are implemented by creating a separate copy of underlying array. It achieves thread-safety by creating a separate copy of List which is a is different way than vector or other collections use to provide thread-safety.Iterator does not throw ConcurrentModificationException even if copyOnWriteArrayList is modified once iterator is created because iterator is iterating over the separate copy of ArrayList while write operation is happening on another copy of ArrayList.

There are two ways to Synchronize ArrayList

  1. Collections.synchronizedList() method – It returns synchronized list backed by the specified list.
  2. CopyOnWriteArrayList class – It is a thread-safe variant of ArrayList.

Collections.synchronizedList()

import java.util.*; 
  
class GFG 
{ 
    public static void main (String[] args) 
    { 
        List<String> list = 
           Collections.synchronizedList(new ArrayList<String>()); 
  
        list.add("practice"); 
        list.add("code"); 
        list.add("quiz"); 
  
        synchronized(list) 
        { 
            // must be in synchronized block 
            Iterator it = list.iterator(); 
  
            while (it.hasNext()) 
                System.out.println(it.next()); 
        } 
    } 
} 

CopyOnWriteArrayList

import java.io.*; 
import java.util.Iterator; 
import java.util.concurrent.CopyOnWriteArrayList; 
  
class GFG 
{ 
    public static void main (String[] args) 
    { 
        // creating a thread-safe Arraylist. 
        CopyOnWriteArrayList<String> threadSafeList 
            = new CopyOnWriteArrayList<String>(); 
  
        // Adding elements to synchronized ArrayList 
        threadSafeList.add("geek"); 
        threadSafeList.add("code"); 
        threadSafeList.add("practice"); 
  
        System.out.println("Elements of synchronized ArrayList :"); 
  
        // Iterating on the synchronized ArrayList using iterator. 
        Iterator<String> it = threadSafeList.iterator(); 
  
        while (it.hasNext()) 
            System.out.println(it.next()); 
    } 
}