o7planning

Java CopyOnWriteArrayList Tutorial with Examples

  1. CopyOnWriteArrayList

1. CopyOnWriteArrayList

CopyOnWriteArrayList is a thread-safe variant of ArrayList. Similar to ArrayList, CopyOnWriteArray manages an array to store its elements. The difference is that all mutative operations such as add, set, remove, clear, ... create a new copy of the array that it is managing.
public class CopyOnWriteArrayList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
Let's see what happens when adding an element to CopyOnWriteArrayList:
The cost to use CopyOnWriteArrayList is very expensive, you have to pay more for resource and performance. However, CopyOnWriteArrayList comes in handy when you cannot or do not want to synchronize traversaling the elements of the list.
For better understanding, consider a situation where two Thread(s) use the same List object. While Thread-A is traversaling the elements of List, it freezes insert or update operations on the List for data integrity, but obviously this affects the operations of Thread-B.
When you create Iterator object from CopyOnWriteArrayList, it helps you traverse the elements of the current array (when Iterator was created). Elements of this array do not change during the existence of Iterator. This is possible because any add, set, remove, clear, .. operations on CopyOnWriteArrayList creates another array that is a copy of the current array.
CopyOnWriteArrayListEx.java
package org.o7planning.copyonwritearraylist.ex;

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

public class CopyOnWriteArrayListEx {

    public static void main(String[] args) {
        // Create a CopyOnWriteArrayList object:
        List<String> list = new CopyOnWriteArrayList<String>();
        list.add("A");
        list.add("B");
        list.add("C");
        
        Iterator<String> iterator1 = list.iterator();
        
        list.add("X1");
        list.add("X2");
        
        Iterator<String> iterator2 = list.iterator();
        
        System.out.println("--- Iterator 1: -----");
        while(iterator1.hasNext()) {
            System.out.println(iterator1.next());
        }
        
        System.out.println("--- Iterator 2: -----");
        while(iterator2.hasNext()) {
            System.out.println(iterator2.next());
        }
    }
}
Output:
--- Iterator 1: -----
A
B
C
--- Iterator 2: -----
A
B
C
X1
X2
Element-changing operations on Iterator themselves (add, set, remove) are not supported. These methods throw UnsupportedOperationException.
Stream
Traversal elements of CopyOnWriteArrayList through Stream has the same results as Iterator.
CopyOnWriteArrayListEx2.java
package org.o7planning.copyonwritearraylist.ex;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Stream;

public class CopyOnWriteArrayListEx2 {

    public static void main(String[] args) {
        // Create a CopyOnWriteArrayList object:
        List<String> list = new CopyOnWriteArrayList<String>();
        list.add("A");
        list.add("B");
        list.add("C");
        
        Stream<String> stream1 = list.stream();
        
        list.add("X1");
        list.add("X2");
        
        Stream<String> stream2 = list.stream();
        
        System.out.println("--- Stream 1: -----");
        stream1.forEach(System.out::println);
        
        System.out.println("--- Stream 2: -----");
        stream2.forEach(System.out::println);
    }
}
Output:
--- Stream 1: -----
A
B
C
--- Stream 2: -----
A
B
C
X1
X2
In addition to the special characteristics mentioned above, CopyOnWriteArrayList is also a common List, You can find other examples of List in the article below: