How can CopyOnWriteArrayList be thread-safe?
If you look at the underlying array reference you'll see it's marked as volatile
. When a write operation occurs (such as in the above extract) this volatile
reference is only updated in the final statement via setArray
. Up until this point any read operations will return elements from the old copy of the array.
The important point is that the array update is an atomic operation and hence reads will always see the array in a consistent state.
The advantage of only taking out a lock for write operations is improved throughput for reads: This is because write operations for a CopyOnWriteArrayList
can potentially be very slow as they involve copying the entire list.
Getting the array reference is an atomic operation. So, readers will either see the old array or the new array - either way the state is consistent. (set(int,E)
computes the new array contents before setting the reference, so the array is consistent when the asignment is made.)
The array reference itself is marked as volatile
so that readers do not need to use a lock to see changes to the referenced array. (EDIT: Also, volatile
guarantees that the assignment is not re-ordered, which would lead to the assignment being done when the array is possibly in an inconsistent state.)
The write lock is required to prevent concurrent modification, which may result the array holding inconsistent data or changes being lost.