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.
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);