![]() So, when you see a stack-trace due to a ConcurrentModificationException, you can not immediately assume that the cause is unsafe multi-threaded access to a Collection. Debugging ConcurrentModificationException Note again that only a "best-effort basis" is required for detection, and a ConcurrentModificationException is explicitly suggested only for the non concurrent (non thread-safe) classes. Concurrent implementations should override this method and, on a best-effort basis, throw an IllegalStateException if it is detected that the mapping function modifies this map during computation and as a result computation would never complete. Non-concurrent implementations should override this method and, on a best-effort basis, throw a ConcurrentModificationException if it is detected that the mapping function modifies this map during computation. The documentation of several methods of the Map interface say this: Note again that the behaviour "cannot be guaranteed" and is only "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. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. 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. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future. The iterators returned are fail-fast: if the is modified at any time after the iterator is created, in any way except through the iterator's own remove method, the Iterator throws a ConcurrentModificationException. The documentation of the HashSet, HashMap, TreeSet and ArrayList classes says this: throwing the exception happens when the concurrent modification is detected, not when it is caused.throwing the exception is on a best-effort basis.throwing the exception cannot be guaranteed.the exception may be throw, not must be thrown.Fail-fast operations throw ConcurrentModificationException on a best-effort basis. 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. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. Note that this exception does not always indicate that an object has been concurrently modified by a different thread. This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible. The documentation of ConcurrentModificationException says: So erroneous use of the Collection does not always result in a thrown ConcurrentModificationException. However, it is in general not possible and practical to guarantee detection of all concurrent modifications. ![]() To help programmers, some implementations of those Collection classes attempt to detect erroneous concurrent modification, and throw a ConcurrentModificationException if they detect it. Using only one thread it is possible to create an iterator for the Collection (using erator(), or an enhanced for loop), start iterating (using Iterator.next(), or equivalently entering the body of the enhanced for loop), modify the Collection, then continue iterating. That unfortunately suggests the only possible cause is simultaneous modification by multiple threads, but that is not so. The Java library calls an attempt to modify a Collection while iterating through it a "concurrent modification". Modification of a Collection while iterating through that Collection using an Iterator is not permitted by most of the Collection classes.
0 Comments
Leave a Reply. |