June 28, 2022

ArrayList Vs CopyOnWriteArrayList in Java

ArrayList is part of Java from version 1.2 where as CopyOnWriteArrayList was added in Java 5 as a thread-safe variant of ArrayList. In this post we’ll see the differences between ArrayList and CopyOnWriteArrayList in Java.

CopyOnWriteArrayList Vs ArrayList in Java

1- Thread Safety:

CopyOnWriteArrayList is thread safe. Thread safety in CopyOnWriteArrayList is achieved by making a fresh copy of the underlying array for all mutative operations (add, set, and so on).

ArrayList in Java is not thread safe.

2- External synchronization:

CopyOnWriteArrayList is already thread safe so no external synchronization needed.

ArrayList can be synchronized externally by using Collections.synchronizedList() method which returns a synchronized List backed by the specified List. Read more about synchronizing ArrayList in this post- How to Synchronize ArrayList in Java

3- Iterator fail-fast or fail-safe:

The iterator returned by CopyOnWriteArrayList is fail-safe and the iterator is guaranteed not to throw ConcurrentModificationException. This array never changes during the lifetime of the iterator, even if there is any mutative operation invoked on the CopyOnWriteArrayList while it is iterated that will result in creation of fresh copy of the underlying array, so interference is impossible.

The iterators returned by ArrayList's iterator and listIterator methods are fail-fast. If the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException.

Here is an example showing the iteration using an iterator with both ArrayList and CopyOnWriteArrayList.

public class ArrayListDemo {
  public static void main(String[] args) {
    List<String> nameList = new ArrayList<String>();
    // adding elements
    nameList.add("Adam");
    nameList.add("Amy");
    nameList.add("Jim");
    nameList.add("Leo");
    // getting iterator
    Iterator<String> itr = nameList.iterator();
    while(itr.hasNext()){
      System.out.println("Name- " + itr.next());
      // adding element while iteration
      nameList.add("Jack");            
    }
  }
}
Output
Name- Adam
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
	at java.util.ArrayList$Itr.next(Unknown Source)
	at com.knpcode.ArrayListDemo.main(ArrayListDemo.java:20)

Here it can be seen that the ConcurrentModificationException is thrown as there is an attempt to add an element to the ArrayList while it is iterated.

With CopyOnWriteArrayList

public class FailSafeDemo {
  public static void main(String[] args) {
    List<String> nameList = new CopyOnWriteArrayList<String>();
    // adding elements
    nameList.add("Adam");
    nameList.add("Amy");
    nameList.add("Jim");
    nameList.add("Leo");
    // getting iterator
    Iterator<String> itr = nameList.iterator();
    while(itr.hasNext()){
      System.out.println("Name- " + itr.next());
      // adding element while iteration
      nameList.add("Jack");            
    }
  }
}
Output
Name- Adam
Name- Amy
Name- Jim
Name- Leo

As you can see now ConcurrentModificationException is not thrown but the iterator doesn’t display the newly added element as it is iterating on a different copy.

4- Performance:

Since the underlying array is copied every time there is a mutative operation, using CopyOnWriteArrayList is ordinarily too costly, but may be more efficient in scenarios where traversal operations vastly outnumber mutations.

ArrayList is not synchronized and underlying array is not copied unless until size of the array has to be changed dynamically so ArrayList is faster.

That's all for the topic ArrayList Vs CopyOnWriteArrayList in Java. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment