Just checked the source code for the HashMap class. In particular search for 'modCount'. The private HashIterator class, for example, keeps a count of the number of times an instance has been modified (except using the 'remove' method) since the instance was created.
For the 'nextEntry' method the count is checked to see if it has changed and may throw that exception. The 'remove' method also checks the count but, if successful, resets the count to the new value. It does this so that you can use the 'remove' method to remove an entry WITHOUT getting the exception.
Other methods (e.g. 'clear') will increment the 'modCount'. As the above code excerpt shows that will cause the exception to be raised the next call of 'nextEntry'.
There are NO guarantees that the exception will be thrown.
The API:
http://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html
Note that fail-fast behavior cannot be guaranteed as it is, generally
speaking, impossible to make any hard guarantees in the presence of
unsynchronized concurrent modification. Fail-fast operations throw
ConcurrentModificationException on a best-effort basis. Therefore, it
would be wrong to write a program that depended on this exception for
its correctness: ConcurrentModificationException should be used only
to detect bugs.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…