Scientech Easy How to Synchronize ArrayList in Java with Examples | Scientech Easy

Monday, October 29, 2018

How to Synchronize ArrayList in Java with Examples

In this tutorial, we will learn how to synchronize ArrayList in Java with example and programs in an easy way and step by step. First of all, we will know in brief the meaning of synchronization so that you do not get any problem to understand the synchronized ArrayList concept.

What is Synchronization in Java?

Technically, Synchronization is the process of allowing only one thread at a time to complete the task entirely. It allows only one thread to access a single resource or single task. When multiple threads access the same resources at the same time then the program may produce an undesirable output. So this problem can be solved by using a technique known as synchronization. The objective of synchronization is to control the access to a shared resource. 

We know that By default the ArrayList class is not a thread-safe or non-synchronized. That means the multiple threads can access the same ArrayList object or instance simultaneously. Therefore, it cannot be used in the multi-threading environment without explicit synchronization because if ArrayList is used in the multi-threading environment without using synchronization then it may produce unpredictable output. So how will we get synchronized ArrayList in Java with thread safety?

How to Synchronize ArrayList object in Java?

There are two methods by which we can get the synchronized version of ArrayList. They are as follows:
1. Using Collections.synchronizedList() method
2. Using CopyOnWriteArrayList
Synchronization of ArrayList,  Synchronized ArrayList.
Ways to synchronize ArrayList in Java

Collections.synchronizedList() method

This method is used to synchronize the collections in Java. The syntax of this method is 
  public static List<T> synchronizedList(List<T> list)

1. It accepts a List which could be the implementation of List interface. For example ArrayList, LinkedList.
2. The return type of this method is a synchronized list(thread safe).
3. synchronizedList is the name of the method. 
4. The parameter list is the list to be wrapped in the synchronize list.
5. T represents the type of generic.
Note: Iterator is used in the synchronization block for synchronization to avoid ConcurrentModificationException in Java. The iterator returned by the synchonized ArrayList is fail-fast. It will throw ConcurrentModificationException when any modification happen in the list during the iteration.

For example
1. ArrayList<String> al=new ArrayList<String>(); // Non-synchronized.
 List l=Collections.synchronizedList(al);
      l➟  synchronized.
     al ➟ Non-synchronized.
2. List<String> synlist=Collections.synchronizedList(new ArrayList<String>);

Similarly, we can get the synchronized version of  Set, Map objects by using the following methods of Collections class.
  public static Set synchronizedList(Set s);
  public static Map synchronizedList(Map m);
Let's see a simple practical program to understand 

Program source code 1:
    package com.deepak.collectiontest; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; public class ArrayListSynchronizationTest { public static void main(String[] args) { // Creates ArrayList Object with Initial capacity of 10. // Non-synchronized ArrayList Object. List<String> l=new ArrayList<String>(); l.add("Apple"); l.add("Orange"); l.add("Banana"); l.add("Pineapple"); l.add("Guava"); // Synchronizing ArrayList in Java List<String> synlist=Collections.synchronizedList(l); // l is non-synchronized. // Here we will use a synchronized block to avoid the non-deterministic behavior. synchronized(synlist){ // Call iterator() method to iterate the ArrayList. Iterator<String> itr=synlist.iterator(); while(itr.hasNext()){ String str=itr.next(); System.out.println(str); } } } }
    Output: Apple Orange Banana Pineapple Guava
In this program, ArrayList achieves the thread-safety by calling synchronized list that locks the whole list into the synchronized block.

Program source code 2: In this program, we will check ConcurrentModificationException by adding a number into the synchronized list during the Iteration.
    package com.deepak.collectiontest; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; public class CMETest { public static void main(String[] args) { ArrayList<Integer> al=new ArrayList<Integer>(); for(int i=0; i < 10; i++) { al.add(i); } List<Integer> synlist=Collections.synchronizedList(al); synchronized(synlist){ Iterator<Integer> itr=synlist.iterator(); while(itr.hasNext()){ al.add(20); // It will throw ConcurrentModificationException because we cannot modify list during Iteration. System.out.println(itr.next()); } } }}
    Output: Exception in thread "main" java.util.ConcurrentModificationException


CopyOnWriteArrayList

1. It creates an empty list.
2. It implements List interface.
3. It creates a list of the elements in the order of specified collection.
4. It is a thread-safe concurrent access of ArrayList. When ArrayList is modified, it will create a fresh copy of the underlying array. 
5. Iterator and ListIterator returned by CopyOnWriteArrayList is completely thread-safe. It will not throw ConcurrentModificationException when ArrayList is modified during iteration.
6. CopyOnWriteArrayList does not lock the whole list. When a thread writes into the list, It simply replace the list by a fresh copy of the underlying array. In this way, it provides the concurrent access of ArrayList for the multiple threads without locking. Since read operation is a thread-safe. Therefore, two threads cannot write into the list simultaneously.
Syntax
CopyOnWriteArrayList<T> al=new CopyOnWriteArrayList<T>(); // T is generic.

Program source code 3:
    package com.deepak.collectiontest; import java.util.Iterator; import java.util.concurrent.CopyOnWriteArrayList; public class ArrayListSynCOWA { public static void main(String[] args) { // Create thread-safe ArrayList. CopyOnWriteArrayList<String> al=new CopyOnWriteArrayList<String>(); al.add("Pen"); al.add("Pencil"); al.add("Copy"); al.add("Eraser"); al.add("Shapner"); System.out.println("Displaying synchronized ArrayList "); // Synchronized block is not required in this method. Iterator<String> itr=al.iterator(); while(itr.hasNext()){ String str=itr.next(); System.out.println(str); } } }
    Output: Displaying synchronized ArrayList Pen Pencil Copy Eraser Shapner
Program source code 4:
    package com.deepak.collectiontest; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; public class ArrayListSynCOWATest { public static void main(String[] args) { CopyOnWriteArrayList<String> al=new CopyOnWriteArrayList<String>(); al.add("A"); al.add("B"); al.add(null); al.add("D"); al.add("E"); al.add("H"); System.out.println(al); List<String> synlist=Collections.synchronizedList(al); // Synchronized block is not required. // Call iterator() method using reference variable synlist. Iterator<String> itr=synlist.iterator(); while(itr.hasNext()){ al.set(5, "F"); // It will not throw ConcurrentModificationException during Iteration. String str=itr.next(); System.out.println(str); } System.out.println(al); } }

    Output: [A, B, null, D, E, H] A B null D E H [A, B, null, D, E, F]
Final words
We hope that this article has covered all practical programs related to this topic. All programs are very important to clear the concepts. So practice all the important programs. We will update regularly various kind of practical problems related to this topic.

Popular