javacopyonwritearraylist

Understanding CopyOnWriteArrayList iterator behavior


I am studying CopyOnWriteArrayList and the situation below got me thinking.

My main method goes like this:

public static void main(String[] args) {
    List<String> list = new CopyOnWriteArrayList<String>();
    list.add("Init1");
    list.add("Init2");
    list.add("Init3");
    list.add("Init4");

    for(String str : list){
        System.out.println(str);
        list.add("PostInit");
    }   
}

In the javadoc I read:

Memory consistency effects: As with other concurrent collections, actions in a thread prior to placing an object into a CopyOnWriteArrayList happen-before actions subsequent to the access or removal of that element from the CopyOnWriteArrayList in another thread.

I was expecting an infinite loop since "actions in a thread prior to placing an object into a CopyOnWriteArrayList happen-before actions subsequent to the access or removal".

But my console output is:

Init1
Init2
Init3
Init4

I believe, I lack some understanding here. Can somebody please help?


Solution

  • From the documentation

    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

    The for-each loop is using the iterator, see https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.14.2.

    Therefore, the for-each loop is going to print the elements which are in the list at the moment the for-loop starts since it is at that moment the iterator is created.