Skip to content
Home » Java CopyOnWriteArrayList

Java CopyOnWriteArrayList

  • by
Java CopyOnWriteArrayList

1. Overview

In this article, we will learn about the Java CopyOnWriteArrayList. To learn more about Java, refer to these articles.

2. Java CopyOnWriteArrayList

This is a thread-safe variant of the ArrayList, introduced in JDK 5 as part of the java.util.concurrent package. This implements the List interface and is useful for handling concurrent executions.

It allows all elements including null.

2.1. Mutable operations

 All mutative operations (add, set, and so on) are implemented by making a fresh copy of the underlying array. For example, the following add method of the CopyOnWriteArrayList creates an internal copy of the array, adds the new element and later updates the actual array.

 public boolean add(E e) {
        synchronized (lock) {
            Object[] es = getArray();
            int len = es.length;
            es = Arrays.copyOf(es, len + 1);
            es[len] = e;
            setArray(es);
            return true;
        }
    }

The lock usage in this code provides memory ordering among threads that use the same lock. Specifically, the unlock at the end of this method provides happens-before semantics with other threads that gain the same lock.

The getArray method does a volatile read of this field, and the setArray method does a volatile write of this field. This guarantees visibility of changes made from one thread to another also as “happens-before” which solves the problem of memory writes that happen in one thread can “leak through” and be seen by another thread.

You can refer this stackoverflow link to understand more on this memory model.

2.2. When to use CopyOnWriteArrayList

This is ordinarily too costly, but may be more efficient than alternatives when read or traversal operations vastly outnumber mutations or alterations such as add, set, update. It is useful when you cannot or don’t want to synchronize traversals, yet need to prevent interference among concurrent threads.

2.3. Java CopyOnWriteArrayList iterator

The “snapshot” style iterator method uses a reference to the state of the array at the point that the iterator was created. This array never changes during the lifetime of the iterator, so interference is impossible, and the iterator is guaranteed not to throw ConcurrentModificationException.

The iterator will not reflect additions, removals, or changes to the list since the iterator was created.

@Test
void testCopyOnWriteArrayList() {
     CopyOnWriteArrayList<String> al = new CopyOnWriteArrayList<String>();
     System.out.println("Initial size of al: " + al.size());
	al.add("C");
	al.add("A");
	al.add("E");
	al.add("B");
	al.add("D");

	System.out.println("Contents of al: " + al);
	try {
		Iterator<String> iterator = al.iterator();
		al.add("Z");
		System.out.println("Contents of al: " + al);
		while(iterator.hasNext()) {
			System.out.println("printing... " + iterator.next());
		}
	} catch(UnsupportedOperationException e) {
		System.out.println("Method not supported:");
	}
	System.out.println("Size of al: " + al.size());
}

We have added ‘Z’ after creating the iterator. So iterator doesn’t reflect the value ‘Z’ while printing the results.

Contents of al: [C, A, E, B, D]
Contents of al: [C, A, E, B, D, Z]
printing... C
printing... A
printing... E
printing... B
printing... D
Size of al: 6

Element-changing operations on iterators themselves (remove, set, and add) are not supported. These methods throw UnsupportedOperationException.

try {
	Iterator<String> iterator = al.iterator();
	al.add("Z");
	System.out.println("Contents of al: " + al);
	while(iterator.hasNext()) {

		System.out.println("printing... " + iterator.next());
		iterator.remove();
	}

} catch(UnsupportedOperationException e) {
	System.out.println("Method not supported:");
}

In the above code, we are trying to remove element using the iterator. This is not permitted as the underlying data set of Iterator is not modifiable.

Contents of al: [C, A, E, B, D, Z]
printing... C
Method not supported:

3. Conclusion

To sum up, we have learned about the Java’s concurrent list CopyOnWriteArrayList.

Leave a Reply

Your email address will not be published. Required fields are marked *