CopyOnWriteArrayList vs ArrayList in Java
CopyOnWriteArrayList is a concurrent Collection class introduced in Java 5 Concurrency API along with its popular cousin ConcurrentHashMap in Java. CopyOnWriteArrayList implements List interface like ArrayList, Vector, and LinkedList but its a thread-safe collection and it achieves its thread-safety in a slightly different way than Vector or other thread-safe collection class. As the name suggests CopyOnWriteArrayList creates a copy of underlying ArrayList with every mutation operation e.g. add, remove, or when you set values. That's why it is only suitable for a small list of values which are read frequently but modified rarely e.g. a list of configurations.
Normally CopyOnWriteArrayList is very expensive because it involves costly Array copy with every writes operation but it's very efficient if you have a List where Iteration outnumbers mutation e.g. you mostly need to iterate the ArrayList and don't modify it too often.
Iterator of CopyOnWriteArrayList is fail-safe and doesn't throw ConcurrentModificationException even if underlying CopyOnWriteArrayList is modified once Iteration begins because Iterator is operating on a separate copy of ArrayList. Consequently, all the updates made on CopyOnWriteArrayList is not available to Iterator (see Java Fundamentals: Collections).
In this Java Collection tutorial we will see What is CopyOnWriteArrayList in Java, Difference between ArrayList and CopyOnWriteArrayList in Java and One simple Java program example on How to use CopyOnWriteArrayList in Java.
Normally CopyOnWriteArrayList is very expensive because it involves costly Array copy with every writes operation but it's very efficient if you have a List where Iteration outnumbers mutation e.g. you mostly need to iterate the ArrayList and don't modify it too often.
Iterator of CopyOnWriteArrayList is fail-safe and doesn't throw ConcurrentModificationException even if underlying CopyOnWriteArrayList is modified once Iteration begins because Iterator is operating on a separate copy of ArrayList. Consequently, all the updates made on CopyOnWriteArrayList is not available to Iterator (see Java Fundamentals: Collections).
In this Java Collection tutorial we will see What is CopyOnWriteArrayList in Java, Difference between ArrayList and CopyOnWriteArrayList in Java and One simple Java program example on How to use CopyOnWriteArrayList in Java.
Difference between CopyOnWriteArrayList and ArrayList in Java.
In the last section, we have seen What is CopyOnWriteArrayList in Java and How it achieves thread-safety by creating a separate copy of List for each writes operation.
Now let's see Some difference between ArrayList and CopyOnWriteArrayList in Java, which is another implementation of List interface :
Now let's see Some difference between ArrayList and CopyOnWriteArrayList in Java, which is another implementation of List interface :
1) First and foremost difference between CopyOnWriteArrayList and ArrayList in Java is that CopyOnWriteArrayList is a thread-safe collection while ArrayList is not thread-safe and can not be used in the multi-threaded environment.
2) The second difference between ArrayList and CopyOnWriteArrayList is that Iterator of ArrayList is fail-fast and throw ConcurrentModificationException once detect any modification in List once iteration begins but Iterator of CopyOnWriteArrayList is fail-safe and doesn't throw ConcurrentModificationException.
3) The third difference between CopyOnWriteArrayList vs ArrayList is that Iterator of former doesn't support remove operation while Iterator of later supports remove() operation. If you want to learn more about collections, I suggest you go through Complete Java MasterClass, one of the best Java course on Udemy.
CopyOnWriteArrayList Example in Java
Here is a complete code Example of CopyOnWriteArrayList which demonstrate that Iterator of CopyOnWriteArrayList doesn't support remove() operation.
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
/**
*
* Java program to demonstrate What is CopyOnWriteArrayList in Java,
import java.util.concurrent.CopyOnWriteArrayList;
/**
*
* Java program to demonstrate What is CopyOnWriteArrayList in Java,
* Iterator of CopyOnWriteArrayList
* doesn’t support add, remove or any modification operation.
*
* @author Java67
*/
public class CopyOnWriteArrayListExample{
public static void main(String args[]) {
CopyOnWriteArrayList<String> threadSafeList = new CopyOnWriteArrayList<String>();
threadSafeList.add("Java");
threadSafeList.add("J2EE");
threadSafeList.add("Collection");
//add, remove operator is not supported by CopyOnWriteArrayList iterator
Iterator<String> failSafeIterator = threadSafeList.iterator();
while(failSafeIterator.hasNext()){
System.out.printf("Read from CopyOnWriteArrayList : %s %n", failSafeIterator.next());
failSafeIterator.remove(); //not supported in CopyOnWriteArrayList in Java
}
}
}
Output:
Read from CopyOnWriteArrayList : Java
Read from CopyOnWriteArrayList : J2EE
Read from CopyOnWriteArrayList : Collection
* doesn’t support add, remove or any modification operation.
*
* @author Java67
*/
public class CopyOnWriteArrayListExample{
public static void main(String args[]) {
CopyOnWriteArrayList<String> threadSafeList = new CopyOnWriteArrayList<String>();
threadSafeList.add("Java");
threadSafeList.add("J2EE");
threadSafeList.add("Collection");
//add, remove operator is not supported by CopyOnWriteArrayList iterator
Iterator<String> failSafeIterator = threadSafeList.iterator();
while(failSafeIterator.hasNext()){
System.out.printf("Read from CopyOnWriteArrayList : %s %n", failSafeIterator.next());
failSafeIterator.remove(); //not supported in CopyOnWriteArrayList in Java
}
}
}
Output:
Read from CopyOnWriteArrayList : Java
Read from CopyOnWriteArrayList : J2EE
Read from CopyOnWriteArrayList : Collection
If we uncomment, commented code in this Java program which modifies CopyOnWriteArrayList using Iterator then we will get following Exception :
Read from CopyOnWriteArrayList : Java
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.concurrent.CopyOnWriteArrayList$COWIterator.remove(CopyOnWriteArrayList.java:1004)
at test.CollectionTest.main(CollectionTest.java:29)
Java Result: 1
Here is a summary of CopyOnWriteArrayList in a slide, it teaches you what all the words have taught you so far:
Further Learning
Thanks for reading this article so far, if you like this article then please share with your friends and colleagues. If you have any feedback or questions then please drop a note.
I love CopyOnWriteArrayList because it doesn't throw any ConcurrentModificatoinException
ReplyDeleteGood Explanation! Easily understandable.helpful. thanks!
ReplyDeletesuperb,by using we can avoid ConcurrentModificationException,
ReplyDeleteWhen we remove object from array list
ArrayList arrayList = new ArrayList();
ReplyDeletearrayList.add("1");
arrayList.add("2");
arrayList.add("3");
Iterator iterator = arrayList.iterator();
while(iterator.hasNext()) {
String value = iterator.next();
if(value.equals("2")) {
System.out.println(arrayList.remove(1));
}
}
Why it is not giving Concurrent Exception?
Try with Multi Threaded env
Deletetry to debug.
DeleteAfter removing element you will not iterate over array, because iterator.hasNext() will false.
change to if(value.equals("1")) and it will throw CME
public static void test(){
DeleteArrayList arrayList = new ArrayList ();
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
Iterator iterator = arrayList.iterator();
while(iterator.hasNext()) {
String value = iterator.next();
if(value.equals("1")) {
System.out.println(arrayList.remove(2));
}
}
}
Really helpful. Thanks!
ReplyDeleteBrilliant Stuff.................. :)
ReplyDelete1. i need to understand internal implementation of CopyOnWriteArrayList if you have something please post it.
ReplyDelete2. why remove operation is not supported by CopyOnWriteArrayList Iterator. There is any logic behind that.
@manav CopyOnWriteArrayList uses cloned object for thread safety so for each thread it will create separate copy of COWAL and later on JVM merges this copy with the original one.So if remove operation was possible you could remove say element "A" from first cloned object but this "A" elenent will be still present in the other copies.
ReplyDeleteMerging would update element "A" again.So remove operation does not make sense so it is not used for COWAL.
your difference between copyonwritearraylist and arraylist not matched with example
ReplyDeleteYes, that's good idea, will put an example as well, thanks.
DeleteSecond difference between ArrayList and CopyOnWriteArrayList is that Iterator of ArrayList is fail-fast and throw ConcurrentModificationException once detect any modification in List once iteration begins but Iterator of CopyOnWriteArrayList is fail-safe and doesn't throw ConcurrentModificationException.
ReplyDeletebut is throws an exception while you are using CopyOnWriteArrayList
Sorry, can you elaborate please?
Deleteits nor correct about
ReplyDeletefailSafeIterator.remove(); //not supported in CopyOnWriteArrayList in Java
its support remove also otherwise no use of copyOnWriteArrayList
Yes I also got the same doubt.
DeleteAs per description given in 1st section of the post is
Purpose of going for **CopyOnWriteArrayList** is as it supports mutation operation e.g. add, remove, or update while iterating through it RIGHT ?
But your example contradicting, by stating that it will not support remove() operation.
Please correct me if my understanding it wrong.
I request you can you please put some more light on it, to clarify the doubt.
~Regards,
Chandan
Its correct. CopyOnWriteArrayList itself supports the remove method. However, the iterator to a CopyOnWriteArrayList does not support the remove() method and consequently throws the UnsupportedOperationException.
Delete