In this article, we will discuss CopyOnWriteArrayList class – the implementation class for List interface in detail
This is the thread-safe version of ArrayList, where modify operation is performed on a separate cloned copy and finally JVM merges both original and cloned copies
Apart from thread-safety difference between ArrayList and CopyOnWriteArrayList, all properties of ArrayList are applicable to CopyOnWriteArrayList
1. CopyOnWriteArrayList:
- CopyOnWriteArrayList is implementation class of List interface (i.e.; CopyOnWriteArrayList implements List)
- For every modify/update operation, a new separate cloned copy is created and modification is performed on cloned copy; while other threads can iterate over original copy
- After modification/updation, JVM takes care of merging both copies (i.e.; original and cloned copy) –> so that we get latest copy with all updation/modification
- Since, every time a new separate cloned copy is created for updation/modification. Therefore, it is suited for multi-threaded environment where there are more number of read/get operation and comparatively less update/modify operation
- While one thread iterating over original copy, other threads can modify with separate cloned copy and compiler won’t throw any ConcurrentModificationException; which isn’t case with ArrayList
- It never throws ConcurrentModificationException while 2 or more threads operating simultaneously i.e.; it is fail-safe iterator
- But, there are certain limitation too with CopyOnWriteArrayList which isn’t case with ArrayList like, while iterating CopyOnWriteArrayList, remove operation isn’t possible and compiler throws UnsupportedOperationException
- Other than above discussed points, all other properties of ArrayList are applicable for CopyOnWriteArrayList too i.e.;
- Insertion-order is maintained
- Duplicate objects are allowed
- Null insertion is possible
- This is introduced in Java 1.5 version
- Present in java.util.concurrent package and implements java.util.List
- Also, implements java.util.RandomAccess, java.lang.Cloneable, java.io.Serializable marker interfaces which provides special ability to CopyOnWriteArrayList (provided by JVM at run time) like,
- java.util.RandomAccess: to access any random element/objects with same speed
- java.lang.Cloneable: to create a duplicate object or to clone an object
- java.io.Serializable: to transfer objects across network
Source: Team BenchResources.Net
2. CopyOnWriteArrayList constructors:
2.1 CopyOnWriteArrayList cowal = new CopyOnWriteArrayList();
- creates an empty CopyOnWriteArrayList object
2.2 CopyOnWriteArrayList cowal = new CopyOnWriteArrayList(Collection c);
- creates an equivalent CopyOnWriteArrayList object for the specified collection
- it is basically used for inter-conversion between collection objects
2.3 CopyOnWriteArrayList cowal = new CopyOnWriteArrayList(Object[] a);
- creates an equivalent CopyOnWriteArrayList object for the specified Object array
3. CopyOnWriteArrayList method:
CopyOnWriteArrayList method | Description |
boolean addIfAbsent(Object o); | to add a new object to CopyOnWriteArrayList, if specified object isn’t present in the invoking list |
int addAllAbsent(Collection c); | to add all objects in the specified collection; only if it is not present in the invoking list |
Note: Apart from above mentioned CopyOnWriteArrayList specific methods, CopyOnWriteArrayList class inherits all methods from List interface
4. CopyOnWriteArrayList Examples:
- Using addAllAbsent() method
- Using combination of addAll() and addAllAbsent() methods
4.1 CopyOnWriteArrayList :
CopyOnWriteArrayListDemo.java
package in.bench.resources.concurrent.collection;
import java.util.ArrayList;
import java.util.concurrent.CopyOnWriteArrayList;
public class CopyOnWriteArrayListDemo {
public static void main(String[] args) {
// COWAL of All capital
CopyOnWriteArrayList<String> allCapital =
new CopyOnWriteArrayList<String>();
allCapital.addIfAbsent("Berlin");
allCapital.addIfAbsent("Tokyo");
allCapital.addIfAbsent("Moscow");
allCapital.addIfAbsent("Tokyo");// again, adding Tokyo
// AL of European capital
ArrayList<String> euroCapital = new ArrayList<String>();
euroCapital.add("Moscow");
euroCapital.add("London");
euroCapital.add("Paris");
// adding European capital to all capital using addAllAbsent()
allCapital.addAllAbsent(euroCapital);
// print to console
System.out.println(allCapital);
}
}
Output:
[Berlin, Tokyo, Moscow, London, Paris]
Explanation:
- 1st list is of type CopyOnWriteArratList which uses addIfAbsent() method to add new elements; only if it isn’t already present in the invoking list (i.e.; COWAL)
- From above output, it is clear though Tokyo is added 2nd time using addIfAbsent() method and it isn’t get added to list
- 2nd list of type ArrayList which is general one and adds new elements using add() method
- There is one final operation being performed in the above demo example; which is adding all elements of ArrayList to CopyOnWriteArrayList using addAllAbsent() method
- Which checks in the invoking COWAL list before adding any elements from specified AL list
- From the output, it is clear that Moscow is already present so it isn’t added to the invoking list
4.2 CopyOnWriteArrayList :
CopyOnWriteArrayListExample.java
package in.bench.resources.concurrent.collection;
import java.util.ArrayList;
import java.util.concurrent.CopyOnWriteArrayList;
public class CopyOnWriteArrayListExample {
public static void main(String[] args) {
// AL of European capital
ArrayList<String> euroCapital = new ArrayList<String>();
euroCapital.add("Moscow");
euroCapital.add("London");
euroCapital.add("Paris");
// AL of Asian capital
ArrayList<String> asiaCapital = new ArrayList<String>();
asiaCapital.add("Tokyo");
asiaCapital.add("Beijing");
asiaCapital.add("Singapore");
// COWAL of All capital
CopyOnWriteArrayList<String> allCapital =
new CopyOnWriteArrayList<String>();
allCapital.add("Berlin");
allCapital.add("Tokyo");
allCapital.add("Moscow");
// adding European capital to all capital using addAll()
allCapital.addAll(euroCapital);
// print to console
System.out.println(allCapital);
// adding Asian capital to all capital using addAllAbsent()
allCapital.addAllAbsent(asiaCapital);
// print to console
System.out.println(allCapital);
}
}
Output:
[Berlin, Tokyo, Moscow, Moscow, London, Paris]
[Berlin, Tokyo, Moscow, Moscow, London, Paris, Beijing, Singapore]
Explanation:
- We have created 2 ArrayList objects of European capitals and Asian capitals
- And also created all mix of capitals of type CopyOnWriteArrayList object
- 1st operation: adding ArrayList to CopyOnWriteArrayList using addAll(Collection) method
- This operation is performed without checking already elements present in the specified list with the invoking list
- As a result, there are duplicates elements in the invoking list after add operation
- From the output, it is seen that there are 2 Moscow elements (i.e.; Moscow present in both specified list and invoking list)
- 2nd operation: adding ArrayList to CopyOnWriteArrayList using addAllAbsent(Collection) method
- This operation is performed after checking invoking list with the specified liste.; if the invoking list already contains any of elements present in the specified list then it is neglected and rest all are added to invoking list
- From the output, it is clear that Tokyo doesn’t get added to the invoking list as it is already present
Related Articles:
- Java 5 – Introduction to Concurrent Collection
- Java 5 – CopyOnWriteArrayList class with example
- Java 5 – CopyOnWriteArrayList with Read and Update operations simultaneously
- Java 5 – Remove operation with CopyOnWriteArrayList and ArrayList
- Java 5 – ArrayList v/s CopyOnWriteArrayList
- Java 5 – CopyOnWriteArrayList v/s SynchronizedList
- Java 5 – Concurrent Collection Interview question and answers
References:
- https://docs.oracle.com/javase/tutorial/collections/intro/
- https://docs.oracle.com/javase/tutorial/collections/interfaces/collection.html
- https://docs.oracle.com/javase/7/docs/api/java/util/Collection.html
- https://docs.oracle.com/javase/tutorial/essential/concurrency/collections.html
- https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CopyOnWriteArrayList.html
Happy Coding !!
Happy Learning !!