Master java skills

CopyOnWriteArrayList

CopyOnWriteArrayList

CopyOnWriteArrayList is part of collections framework with some differences with ArrayList. CopyOnWriteArrayList is thread safe and can be used in multithreaded environment. Let’s have a look at the features of CopyOnWriteArrayList

  1. The CopyOnWriteArrayList is a thread safe version of ArrayList. If we are making modifications like adding, removing elements in CopyOnWriteArrayList, then JVM does so by creating a new copy of it by the use of Cloning.
  2. CopyOnWriteArrayList is costly if used in case of more update operations. Because when changes are made, JVM has to create a cloned copy of the underlying array and add/update elements to it.
  3. Multiple threads can read the data from CopyOnWriteArrayList, but only one thread can write data at a particular time.
  4. We can add duplicate elements in it.
  5. CopyOnWriteArrayList is the best choice in multithreading, if there are more read operations.

Class hierarchy

Constructor Summary

CopyOnWriteArrayList()
CopyOnWriteArrayList(Collection<? extends E> c)
CopyOnWriteArrayList(E[] toCopyIn)

CopyOnWriteArrayList Example

package com.javatrainingschool;

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("CV Raman", "Homi Bhabha", "Ramanujan");
		CopyOnWriteArrayList<String> cowArrayList = new CopyOnWriteArrayList<String>(list);

		System.out.println("List = " + cowArrayList);

		Iterator<String> iterator1 = cowArrayList.iterator();

		// adding another element
		cowArrayList.add("Vikram Sarabhai");

		while(iterator1.hasNext()) {
			System.out.println("Element from iterator1 : " + iterator1.next());
		}
		
		Iterator<String> iterator2 = cowArrayList.iterator();
		
		while(iterator2.hasNext()) {
			System.out.println("Element from iterator2 : " + iterator2.next());
		}
	}
}
Output :
List = [CV Raman, Homi Bhabha, Ramanujan]
Element from iterator1 : CV Raman
Element from iterator1 : Homi Bhabha
Element from iterator1 : Ramanujan
Element from iterator2 : CV Raman
Element from iterator2 : Homi Bhabha
Element from iterator2 : Ramanujan
Element from iterator2 : Vikram Sarabhai

How CopyOnWriteArrayList work internally?

CopyOnWriteArrayList class does every write operation (add, set, remove, etc) in a new copy of the list. JVM creates a new copy of the list and modifications are done in that. Using this technique, thread-safety is achieved without a need for synchronization.

Note -> Any number of reader threads can access CopyOnWriteArrayList simultaneously. And reader and writer threads do not block each other.

CopyOnWriteArrayList internal working

When we call iterator() or listIterator() methods on CopyOnWriteArrayList, it returns an iterator object that holds immutable snapshot of the list objects. After iterator is created, if any other thread makes changes in the list, then that will not reflect in iterator objects. Due to which, we can iterate over the list in a safe way, without bothering about the concurrent modification.

CopyOnWriteArrayList is useful in following cases:

  1. When we need to use a list in a multithreaded environment, then multiple threads can perform read and write operations simultaneously.
  2. When read operations are more and write operations are less. If it is vice versa, then we can use Vector or synchronized list.

CopyOnWriteArraySet

CopyOnWriteArraySet is like CopyOnWriteArrayList. It is thread safe version of HashSet.

Class declaration

class CopyOnWriteArraySet<E> extends AbstractSet<E> implements java.io.Serializable

Constructor summary

CopyOnWriteArraySet()
CopyOnWriteArraySet(Collection<? extends E> c)

Example

package com.javatrainingschool;

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

public class CopyOnWriteArrayListExample {

	public static void main(String[] args) {
		List<String> list = Arrays.asList("CV Raman", "Homi Bhabha", "Ramanujan", "Ramanujan", "Homi Bhabha");
		CopyOnWriteArraySet<String> cowArraySet = new CopyOnWriteArraySet<String>(list);

		System.out.println("Set = " + cowArraySet);

		Iterator<String> iterator1 = cowArraySet.iterator();

		// adding another element
		cowArraySet.add("Vikram Sarabhai");

		while(iterator1.hasNext()) {
			System.out.println("Element from iterator1 : " + iterator1.next());
		}
		
		Iterator<String> iterator2 = cowArraySet.iterator();
		
		while(iterator2.hasNext()) {
			System.out.println("Element from iterator2 : " + iterator2.next());
		}
	}
}
Output :
Set = [CV Raman, Homi Bhabha, Ramanujan]
Element from iterator1 : CV Raman
Element from iterator1 : Homi Bhabha
Element from iterator1 : Ramanujan
Element from iterator2 : CV Raman
Element from iterator2 : Homi Bhabha
Element from iterator2 : Ramanujan
Element from iterator2 : Vikram Sarabhai