Site icon JavaGoal

CopyOnWriteArrayList in java

In recent posts, we have read mutable list and immutable list in java. The immutable ArrayList in java is used in multithreading because it’s thread-safe. In this post, we will discuss another thread-safe ArrayList that is CopyOnWriteArrayList in java.

Here is the table content of the article will we will cover this topic.
1. What is CopyOnWriteArrayList in java?
2. Important Points of CopyOnWriteArrayList in java?
3. Constructors of CopyOnWriteArrayList in java?
4. How to create CopyOnWriteArrayList in java?
5. How does CopyOnWriteArrayList work internally?
6. When to use CopyOnWriteArrayList or need of CopyOnWriteArrayList?

1. What is CopyOnWriteArrayList in java

The CopyOnWriteArrayList class is also part of the Java Collection framework which implements the List, Cloneable, RandomAccess, and Serializable interface.
A CopyOnWriteArrayList is similar to an ArrayList but it has some additional features like thread-safe. This class is existing in java.util.concurrent.
You already know, ArrayList is not thread-safe. We can’t use the ArrayList in the multi-threaded environment because it creates a problem in ArrayList values.

2. Important Points of CopyOnWriteArrayList in java

1. The CopyOnWriteArrayList is an enhanced version of ArrayList. If you are making any modifications(add, remove, etc.)  in  CopyOnWriteArrayList then JVM creates a new copy by use of Cloning.
2. The CopyOnWriteArrayList is costly if we want to update operations. Because whenever we make any changes the JVM creates a cloned copy of the underlying array and add/update element to it.
3. It is a thread-safe version of ArrayList. Multiple threads can read the data but only one thread can write the data at one time.
4. CopyOnWriteArrayList is the best choice if we want to perform read operation frequently.
5. The CopyOnWriteArrayList is a replacement of a synchronized List. Because it offers better concurrency when iterations outnumber mutations.
6. We can add duplicate elements in it and also heterogeneous Objects, but we should use generics to ignore compile-time errors.
7. In CopyOnWriteArrayList the removal operation of the Iterator is not supported. If you will try this it will throw a Run-time exception saying UnsupportedOperationException.

3. Constructors of CopyOnWriteArrayList in java

CopyOnWriteArrayList c = new CopyOnWriteArrayList(); 

It creates an empty list in memory. This constructor is useful when you want to create a list without any value.

CopyOnWriteArrayList c = new CopyOnWriteArrayList(Collection obj);

It creates a list that containing all the elements that is specified collection. This constructor is useful when you want to create a CopyOnWriteArrayList from existing collection.

CopyOnWriteArrayList c = new CopyOnWriteArrayList(Object[] obj) ;

It Creates a list that containing all the elements that is specified Array. This constructor is useful when you want to create a CopyOnWriteArrayList from Array.

4. How to create CopyOnWriteArrayList in java?

To create a CopyOnWriteArrayList we must use the constructor of CopyOnWriteArrayList. There are number of constructors that is used to create list.

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class CopyOnWriteArrayListExample
{
	public static void main(String[] args) 
	{
		List<String> list = Arrays.asList("Ram", "Ravi", "Krishan");
		CopyOnWriteArrayList<String> copyOnWriteList = new CopyOnWriteArrayList<String>(list);
		 
		System.out.println("Without modification = "+copyOnWriteList); 
		 
		//Get iterator 
		Iterator<String> iterator1 = copyOnWriteList.iterator();
		 
		//Add one element and verify list is updated
		copyOnWriteList.add("Hi");
		 
		System.out.println("After modification = "+copyOnWriteList);   
		 
		//Get iterator 2
		Iterator<String> iterator2 = copyOnWriteList.iterator();
		 
		System.out.println("Element from first Iterator:");
		iterator1.forEachRemaining(System.out :: println);
		System.out.println("Element from Second Iterator:");
		iterator2.forEachRemaining(System.out :: println);   
	}
}

Output: Without modification = [Ram, Ravi, Krishan]
After modification = [Ram, Ravi, Krishan, Hi]
Element from first Iterator:Ram
Ravi
Krishan
Element from Second Iterator:Ram
Ravi
Krishan
Hi

In the above program we created a CopyOnWriteArrayList and after that add a new value in list. When we added the value in list the JVM created another list internally.
You can check the iterator1 and iterator2. The iterator1 and iterator2 have different values.

5. How does CopyOnWriteArrayList work internally?

The CopyOnWriteArrayList class using a mechanism in which every write operation (add, set, remove, etc) the JVM creates a new copy of the elements in the list. By use of this technique its thread-safe without a need for synchronization.

Let’s say we are adding some value in CopyOnWriteArrayList then JVM creates a new copy. Let’s have a look on code.

public boolean add(E e) {
        synchronized (lock) {
            Object[] es = getArray();
            int len = es.length;
            es = Arrays.copyOf(es, len + 1);
            es[len] = e;
            setArray(es);
            return true;
        }
    }

In add() method the write operation acquires a separate lock before executing a write operation, and all write operations use this same lock. It means only one thread can perform write operation at a time.

final void setArray(Object[] a) 
{
  array = a;
}

After that it gets the array and set to new array. 

NOTE: As you know the read operations do not acquire any lock. It means multiple threads can perform read operations simultaneously. The read and write operations do not block each other.

When we are calling the iterator() and listIterator() method on the CopyOnWriteArrayList it returns an iterator object that holds immutable snapshot of the elements. After creation of Iterator, if any other thread making changes in list that will not reflated in iterator object.
Due to this simple fact, we can iterate over the list in a safe way, even doesn’t care about the concurrent modification.

Memory representation of above program

6. When to use CopyOnWriteArrayList or need of CopyOnWriteArrayList?

Whenever we are using concept in Java, we must thing when to use it or what is the need of concept. You should be aware the use case of CopyOnWriteArrayList.

We can use CopyOnWriteArrayList rather than the ArrayList for following cases

1. Thread safe

The CopyOnWriteArrayList is thread safe variant of ArrayList.  Let’s say you want to work in multithread environment then you should choose the CopyOnWriteArrayList. Because you can perform read and write operation by multiple threads.
Reason: Because ArrayList is not thread safe. In ArrayList different threads make different changes that leads to inaccuracy of data. But in case of CopyOnWriteArrayList, whenever any thread makes changes in list, the JVM creates a new copy of list internally. So that value is updated for the all threads. 

Note: In CopyOnWriteArrayList only one thread can perform write operation at a time But multiple threads can perform read operations simultaneously.

2. Minimum modification and frequently read operation

As you already know CopyOnWriteArrayList is very costly because whenever you make any modification in list it creates a fresh new copy of list.  So, you should use the CopyOnWriteArrayList when the number of write operations is very small as compared to the read operations.
Reason: Let’s say you are creating a list from CopyOnWriteArrayList that contains 10000 objects.

CopyOnWriteArrayList<String> copyOnWriteList = new CopyOnWriteArrayList<String>(listOfthousands);

Suppose you are adding three more elements in list.

copyOnWriteList.add(“HI”);

copyOnWriteList.add(“Hello”);

copyOnWriteList.add(“Hey”);

Each time, The JVM creates a new fresh copy of list. It means JVM creates three new copies for three operations. Now you think if you are doing number of modification in list it will be very costly.

3. Don’t want to use synchronized ArrayList

As you know we can make a thread safe ArrayList by use synchronization. But synchronized ArrayList has some  limitation. In synchronized list all the read and write methods are synchronized. It means if a thread performs write operation, it blocks other threads even they just want to perform only read operations.
Reason: CopyOnWriteArrayList provide some more flexibility than synchronization.
1. In CopyOnWriteArrayList multiple threads can perform read operations concurrently.
2. If one thread performing read operation meanwhile another thread can write operation concurrently.3. One thread can perform write operation while other threads can execute read operations simultaneously.

Exit mobile version