Search code examples
javaconcurrencyconcurrentmodification

Concurrent modification of a list while using copy constructor


Will the following code cause a ConcurrentModificationException or other side effects?

ArrayList<String> newList = new ArrayList<String>(list);

Considering that the size of list is very huge and another thread is concurrently modifying the list when above code is getting executed.


Solution

  • Edit:

    My initial response is yes but as @JohnVint correctly points out, it won't be a ConcurrentModificationException since under the covers ArrayList is duplicating the array using System.arrayCopy(...). See the code snippets at the end.

    The problem is that another thread is making changes to the element array as you do this copy. You might get IndexOutOfBoundsException, uninitialized array values, or even some sort of native memory access exception since System.arraycopy(...) is done in native code.

    You will need to synchronize on the list during both the update and the copy to protect against these race condition as well as establish the memory barrier to make sure the element array that backs the ArrayList is appropriately up-to-date.


    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        ...
    }
    
    // ArrayList
    public Object[] toArray() {
            return Arrays.copyOf(elementData, size);
    }
    
    // Arrays
    public static <T,U> T[] copyOf(U[] original, int newLength,
        Class<? extends T[]> newType) {
        ...
        System.arraycopy(original, 0, copy, 0,
            Math.min(original.length, newLength));
    }
    
    // System
    public static native void arraycopy(Object src,  int  srcPos,
        Object dest, int destPos, int length);