Java concurrency: Understanding CopyOnWriteArrayList and CopyOnWriteArraySet

Java has a huge amount of useful collections and several are made specifically for use in concurrent code like the ConcurrentHashMap.

Two sometimes very useful classes are the CopyOnWriteArrayList and CopyOnWriteArraySet. They implement the java.util.List and the java.util.Set interface respectively.

Let’s focus on the CopyOnWriteArrayList to understand what it is all about. Contrary to the ArrayList, this class is thread safe. This means when you use it from several threads no undefined state can occur in the list.
As will all data structures it is important to understand when to use them. As the name CopyOnWrite says, a copy of the whole list is made each time you write to the list like adding an element or remove an element. As you can figure out yourself, this can be pretty expensive when your list is large.
This means that a CopyOnWriteArrayList (and CopyOnWriteArraySet) is mostly useful when you have few modifications but many reads because reads are very cheap and don’t require synchronization.

When you iterate over a CopyOnWriteArrayList and CopyOnWriteArraySet the iterator uses a snapshot of the underlying list (or set) and does not reflect any changes to the list or set after the snapshot was created. The iterator will never throw a ConcurrentModificationException.

Here is a code example:

import java.util.Arrays;
import java.util.concurrent.CopyOnWriteArrayList;

public class CopyOnWriteTest {

	public static void main(String[] args) throws InterruptedException {

		final CopyOnWriteArrayList<Integer>; numbers = new CopyOnWriteArrayList<>(
				Arrays.asList(1, 2, 3, 4, 5));

		// new thread to concurrently modify the list
		new Thread(new Runnable() {
			public void run() {
				try {
					// sleep a little so that for loop below can print part of
					// the list
				} catch (InterruptedException e) {
				System.out.println(&quot;numbers:&quot; + numbers);

		for (int i : numbers) {
			// sleep a little to let other thread finish adding an element
			// before iteration is complete

Note: This is not production ready code, no proper exception handling, etc

Here is the output of this code:

numbers:[1, 2, 3, 4, 5, 10]

As you can see the for loop only prints the numbers 1-5 and the number 10 is not printed in the for loop as it was not present when the snapshot of the iterator was taken.

CopyOnWriteArrayList and CopyOnWriteArraySet (which is implemented with a CopyOnWriteArrayList) are special data structures for use cases where you want to share the data structure among several threads and have few writes and many reads.
Always make sure to do a performance test for your code on real hardware to see how it performs in your application. And make sure to read the javadoc for all the methods to really understand how the data structures work.
Of course you can also use CopyOnWriteArrayList and CopyOnWriteArraySet from other JVM languages like Scala, Clojure, JRuby or Groovy.

Immutable collections.
Sometimes you just need to create the list or set once and then later only read from it. In this case I recommend having a look at the immutable collections from Guava.. They are always thread safe (as is every really immutable object) and are a better alternative to the wrapped immutable collections that come with the JDK. See the Guava website for why that is the case.