javalistconcurrencyconcurrentmodification

Is modCount an atomic variable?


I read that a ConcurrentModificationException can be thrown whenever a thread performs a structural modification upon a certain list while another thread is iterating over its elements. To detect such modification, instances of the class List store the number of times they were modified in a field called modCount, whose value is checked at each iteration of the list to check whether the latter was modified. If my understanding was correct, access to modCount needs to be synchronized, because if the list in question was to be modified after checking the value of modCount in the last iteration and before the end of the loop, the iterator would fail to detect that the list was modified during its last iteration.


Solution

  • Everything you've said is correct, and perfectly normal. modCount is not atomic, and the iterator could fail to detect that the list was modified, and that's fine. Revisit the ArrayList documentation:

    Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.

    Because ArrayList does not try to guarantee that it will always detect a concurrent modification, it can avoid the overhead of an atomic variable for a case that should never happen in correct code. The use of the unsynchronized modCount detects the most common cases, and will sometimes (depending on exact thread ordering and the like) detect cases that are truly concurrent. Remember, though, that ConcurrentModificationException almost never happens because concurrency is actually going on, but because someone calls a modification method during an iteration loop.