Java program to synchronization of ArrayList

The implementation of arrayList is asynchronous by default. This means that if a thread modifies it structurally and multiple threads access it at the same time, it must be synchronized externally. Structural modification means adding or removing elements from the list or explicitly adjusting the size of the backing array. Changing the value of an existing element is not a structural modification.

There are two way to create Synchronized Arraylist.
1. Collections.synchronizedList() method.
2. Using CopyOnWriteArrayList.

Method 1: Using Collections.synchronizedList() method

To perform serial access, all access to the backup list must be completed by returning the list. When iterating the returned list, the user must manually synchronize it.

 

public static  List synchronizedList(List list)
Accepts a List which could be implementation of List 
interface. e.g. ArrayList, LinkedList.
Returns a Synchronized(thread-safe) list backed by the 
specified list.
Parameter list is the list to be wrapped in a synchronize list.
T represents generic

 

// Java program to demonstrate working of
// Collections.synchronizedList
import java.util.*;

class GFG
{
	public static void main (String[] args)
	{
		List list =
		Collections.synchronizedList(new ArrayList());

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

Output:

 

practice
code
quiz

Method 2: Using CopyOnWriteArrayList

 

 CopyOnWriteArrayList threadSafeList = new CopyOnWriteArrayList();
  
  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, where all variable operations (such as adding, setting, deleting...) are implemented by creating a separate copy of the underlying array. It achieves thread safety by creating a single copy of the List, which is different from the way vectors or other collections provide thread safety.

  • Useful when you can't or don't want to keep the loop in sync but need to avoid interference between simultaneous threads.
  • It's expensive because it contains a separate copy of the array for each write (e.g. add, set, delete...)
  • This is especially effective when you have a list and check its items and don't have to change it often.

Even if copyOnWriteArrayList is modified after the iterator is created, the iterator will not throw ConcurrentModificationException because the iterator is iterating a separate copy of the ArrayList and the write operation is occurring on another copy of the ArrayList.

 

// 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 threadSafeList
			= new CopyOnWriteArrayList();

		// 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 it = threadSafeList.iterator();

		while (it.hasNext())
			System.out.println(it.next());
	}
}

Output:

Elements of synchronized ArrayList :
geek
code
practice

What happens if we try to modify CopyOnWriteArrayList through iterator’s own method?

If you try to modify CopyOnWriteArrayList through the iterator's own methods (such as add(), set(), remove()), it will throw an UnsupportedOperationException.

 

// 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 threadSafeList =
			new CopyOnWriteArrayList();

		// 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 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 to use arrayList when vector is synchronized?

  1. Performance: Vector is synchronized and thread-safe and therefore slightly slower than ArrayList.
  2. Functionality: Vectors are synchronized at the level of each individual operation. Usually, a programmer likes to synchronize the entire sequence of operations. Synchronizing individual processes is less secure and slower.
  3. Obsolete vectors: Vectors are considered deprecated and unofficially rejected in Java. In addition, a vector is synchronized for each operation, which is almost never done. Most Java programmers prefer to use ArrayList because they will most likely sync arrayList explicitly if it needs to be synced.

 

Submit Your Programming Assignment Details