Synchronization of ArrayList in Java
Last Updated :
03 Dec, 2021
Implementation of ArrayList is not synchronized by default. It means if a thread modifies it structurally and multiple threads access it concurrently, it must be synchronized externally. Structural modification implies the addition or deletion of element(s) from the list or explicitly resizes the backing array. Changing the value of an existing element is not a structural modification.
There are two ways to create a Synchronized ArrayList.
1. Collections.synchronizedList() method.
2. Using CopyOnWriteArrayList.
Method 1: Using Collections.synchronizedList() method
To do serial access, all access to the backing list must be accomplished through the returned list. It is imperative that the user manually synchronizes on the returned list when iterating over it.
public static List<T> synchronizedList(List<T> list)
- Accepts a List which could be the implementation of the List interface. e.g. ArrayList, LinkedList.
- Returns a Synchronized(thread-safe) list backed by the specified list.
- The parameter list is the list to be wrapped in a synchronized list.
- T represents generic
Java
// Java program to demonstrate working of
// 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());
}
}
}
Method 2: Using CopyOnWriteArrayList
CopyOnWriteArrayList<T> threadSafeList = new CopyOnWriteArrayList<T>();
- Create an empty List.
- It implements List interface.
- It is a thread-safe variant of ArrayList.
- T represents generic
A thread-safe variant of ArrayList in which all mutative operations (e.g., add, set, remove..) are implemented by creating a separate copy of an underlying array. It achieves thread safety by creating a separate copy of the List which is different than vector or other collections used to provide thread-safety.
- It is useful when you can't or don't want to synchronize the traversal yet need to prevent interference among concurrent threads.
- It is costly as it involves separate Array copy with every write operation(e.g., add, set, remove.)
- It is very efficient when you have List and need to traverse its elements and don't modify it often.
The iterator does not throw ConcurrentModificationException even if copyOnWriteArrayList is modified once the iterator is created. The iterator is iterating over the separate copy of ArrayList while a write operation is happening on another copy of ArrayList.
Java
// Java program to illustrate the thread-safe ArrayList.
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());
}
}
OutputElements of synchronized ArrayList :
geek
code
practice
What happens if we try to modify CopyOnWriteArrayList through the iterator's method?
It throws UnsupportedOperationException if you try to modify CopyOnWriteArrayList through iterator's own method(e.g. add(), set(), remove()).
Java
// Java program to illustrate the thread-safe ArrayList
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())
{
String str = it.next();
it.remove();
}
}
}
Runtime Error:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.concurrent.CopyOnWriteArrayList$COWIterator.remove
(CopyOnWriteArrayList.java:1176)
at GFG.main(File.java:28)
Other constructors of CopyOnWriteArrayList
1. CopyOnWriteArrayList(Collection<? extends E> c): Creates a list containing the elements of the specified collection, in the order, they are returned by the collection's iterator.
2. CopyOnWriteArrayList(E[] toCopyIn): Creates a list holding a copy of the given array.
Why use ArrayList when the vector is synchronized?
- Performance: Vector is synchronized and thread-safe, and because of this, it is slightly slower than ArrayList.
- Functionality: Vector synchronizes at the level of each individual operation. Generally, a programmer likes to synchronize a whole sequence of operations. Synchronizing individual operations is both less safe and slower.
- Vectors obsolete: Vectors are considered obsolete and unofficially deprecated in java. Also, the vector synchronizes on each individual operation which is almost never done. Mostly java programmers prefer using ArrayList since they will probably synchronize the arrayList explicitly anyway if they need to synchronize.
Must Read: Vector vs ArrayList in Java
Similar Reads
Static Synchronization in Java Synchronization is the potential to regulate the access of multiple threads to any shared resource. Synchronization in Java is essential for reliable communication between threads. It is achieved in Java with the use of synchronized keywords. Important Points Regarding Synchronization It is only for
5 min read
Importance of Thread Synchronization in Java Thread synchronization in Java is important for managing shared resources in a multithreaded environment. It ensures that only one thread can access a shared resource at a time, which enhances the overall system performance and prevents race conditions and data corruption.Why is Thread Synchronizati
8 min read
Join two ArrayLists in Java Given two ArrayLists in Java, the task is to join these ArrayLists. Examples:Input: ArrayList1: [Geeks, For, ForGeeks] , ArrayList2: [GeeksForGeeks, A computer portal] Output: [Geeks, For, ForGeeks, GeeksForGeeks, A computer portal] Input: ArrayList1: [G, e, e, k, s] , ArrayList2: [F, o, r, G, e, e,
1 min read
Java Method and Block Synchronization In Java, Synchronization is very important in concurrent programming when multiple threads need to access shared resources. Java Synchronization can be applied to methods and blocks. Method synchronization in Java locks the entire method and Block synchronization locks only a specific section of the
6 min read
Vector vs ArrayList in Java ArrayList and Vectors both implement the List interface, and both use (dynamically resizable) arrays for their internal data structure, much like using an ordinary array. Syntax: ArrayList: ArrayList<T> al = new ArrayList<T>(); Vector: Vector<T> v = new Vector<T>(); ArrayList
4 min read