Class ConcurrentModificationException
For example, it is not generally permissible for one thread to modify a Collection while another thread is iterating over it. In general, the results of the iteration are undefined under these circumstances. Some Iterator implementations (including those of all the general purpose collection implementations provided by the JRE) may choose to throw this exception if this behavior is detected. Iterators that do this are known as fail-fast iterators, as they fail quickly and cleanly, rather that risking arbitrary, non-deterministic behavior at an undetermined time in the future.
Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.
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.
Избавляемся от ConcurrentModificationException
Как известно, ConcurrentModificationException к многопоточности никакого отношения не имеет. Возникает эта гадость, когда мы пытаемся модифицировать коллекцию во время итерирования по ней. Как обычно, это имеет исторические корни: коллекции и итераторы появились в Java 1.2, в те времена избежать явного использования итератора при обходе коллекции было никак нельзя, так что предложение менять коллекцию посредством методов итератора не выглядело совсем ужасным:
Не, всё же выглядело. Но никаких других вариантов не было. Позже в пятой джаве появляется цикл foreach, и использование итераторов становится преимущественно неявным:
«Ишь чего захотели! Юзайте явные итераторы, дорогие кастомеры, и не выделывайтесь» — наверное что-то такое думали разработчики джава платформы работая над пятеркой.
В шестой джаве появляется пакет конкаренси. Теперь можно cделать так:
И получить set который не кидается ConcurrentModificationException-ами. Но опять же счастье не совсем полное:
- Oбычно многопоточность нам вовсе не нужна
- Не подерживаются null ни в качестве элементов, ни ключей, ни значений. Да и ладно, честно сказать.
- Порядок элементов не определён и может меняться — вот это гораздо хуже. Т.е. если мы бежим по элементам и ведём некий подсчёт с потерей точности, то нас могут поджидать неприятные сюрпризы и разные результаты на одних и тех же наборах данных, что, скажем, не всегда хорошо. Так же бывают задачи, где желательно сохранить именно изначальный порядок данных. Ну и вот такие штуки тоже имеют место быть:
- В рамках одного треда можно добавлять и удалять элементы в любой момент без всяких эксепшенов. И конечно же за константное время.
- Можно хранить null-ы, если вдруг хочется.
- Элементы обходятся в том порядке в котором были добавлены.
- Удаляя элемент мы не будем обнулять ссылку на следующий, т. е. eсли итератор стоит на данном элементе, то он сможет пройти дальше.
- В конце списка поместим фэйковый элемент, который превращается в настоящий когда в список что-нибудь добавляют. Т.е. даже добравшись до конца списка итератор не упирается в null и может продолжить работу если в коллекции появляется новый элемент. Далее в коде этот фейковый элемент называется placeholder.

- В начале у нас есть элементы A, B, C, D.
- Затем элементы C и D удаляются.
- Добавляется новый элемент E.
Ну и для константного времени доступа нам, очевидно, нужен хэшмап:
Теперь можно делать так:
Понятно, что аналогично можно сконструировать и LinkedMap. Вот в общем-то и всё, ещё один велосипед готов. Почему подобным образом не доработали библиотечные LinkedHashMap и LinkedHashSet? Кто знает, возможно чтобы джависты завидовали джаваскриптистам.
ConcurrentModificationException in Java
![]()
The ConcurrentModificationException occurs when an object is tried to be modified concurrently when it is not permissible. This exception usually comes when one is working with Java Collection classes.
For Example : It is not permissible for a thread to modify a Collection when some other thread is iterating over it. This is because the result of the iteration becomes undefined with it. Some implementation of the Iterator class throws this exception, including all those general-purpose implementations of Iterator which are provided by the JRE. Iterators which do this are called fail-fast as they throw the exception quickly as soon as they encounter such situation rather than facing undetermined behavior of the collection any time in the future.
It is not mandatory that this exception will be thrown only when some other thread tries to modify a Collection object. It can also happen if a single thread has some methods called which are trying to violate the contract of the object. This may happen when a thread is trying to modify the Collection object while it is being iterated by some fail-fast iterator, the iterator will throw the exception.
Let’s see the concurrent modification exception scenario with an example:
Above program will throw java.util.ConcurrentModificationException when executed, as shown in below console logs.
From the output stack trace, it’s clear that the concurrent modification exception is thrown when we call iterator next() function.
If you are wondering how Iterator checks for the modification, it’s implementation is present in the AbstractList class, where an int variable modCount is defined. The modCount provides the number of times list size has been changed. The modCount value is used in every next() call to check for any modifications in a function checkForComodification() .
Now, comment out the list part and run the program again. You will see that there is no ConcurrentModificationException being thrown now.
Output: Map Value:3 Map Value:2 Map Value:4
Since we are updating the existing key value in the myMap, its size has not been changed and we are not getting ConcurrentModificationException. The output may be different in your system because HashMap keyset is not ordered like a List. If you will uncomment the statement where I am adding a new key-value in the HashMap, it will cause Concurrent Modification Exception.
To Avoid ConcurrentModificationException in multi-threaded environment
- You can convert the list to an array and then iterate on the array. This approach works well for small or medium size list but if the list is large then it will affect the performance a lot.
- You can lock the list while iterating by putting it in a synchronized block. This approach is not recommended because it will cease the benefits of multithreading.
- If you are using JDK1.5 or higher then you can use ConcurrentHashMap or SynchronizedMap and CopyOnWriteArrayList classes. This is the recommended approach to avoid concurrent modification exception.
- One more solution is here, you can simple copy all keys in List and iterate on that list of keys.
Single Thread Environment : Use for loop to avoid java.util.ConcurrentModificationException
If you are working on single-threaded environment and want your code to take care of the extra added objects in the list then you can do so using for loop rather than an Iterator.
Note that I am decreasing the counter because I am removing the same object, if you have to remove the next or further far object then you don’t need to decrease the counter. Try it yourself.
One More Thing: You will get ConcurrentModificationException if you will try to modify the structure of the original list with subList.
Why is a ConcurrentModificationException thrown and how to debug it
I am using a Collection (a HashMap used indirectly by the JPA, it so happens), but apparently randomly the code throws a ConcurrentModificationException . What is causing it and how do I fix this problem? By using some synchronization, perhaps?
Here is the full stack-trace:
![]()
![]()
8 Answers 8
This is not a synchronization problem. This will occur if the underlying collection that is being iterated over is modified by anything other than the Iterator itself.
This will throw a ConcurrentModificationException when the it.hasNext() is called the second time.
The correct approach would be
Assuming this iterator supports the remove() operation.
![]()
Try using a ConcurrentHashMap instead of a plain HashMap
![]()
Modification of a Collection while iterating through that Collection using an Iterator is not permitted by most of the Collection classes. The Java library calls an attempt to modify a Collection while iterating through it a "concurrent modification". That unfortunately suggests the only possible cause is simultaneous modification by multiple threads, but that is not so. Using only one thread it is possible to create an iterator for the Collection (using Collection.iterator() , 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.
To help programmers, some implementations of those Collection classes attempt to detect erroneous concurrent modification, and throw a ConcurrentModificationException if they detect it. However, it is in general not possible and practical to guarantee detection of all concurrent modifications. So erroneous use of the Collection does not always result in a thrown ConcurrentModificationException .
This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.
Note that this exception does not always indicate that an object has been concurrently modified by a different thread. 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 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.
- the exception may be throw, not must be thrown
- different threads are not required
- throwing the exception cannot be guaranteed
- throwing the exception is on a best-effort basis
- throwing the exception happens when the concurrent modification is detected, not when it is caused
The documentation of the HashSet , HashMap , TreeSet and ArrayList classes says this:
The iterators returned [directly or indirectly from this class] are fail-fast: if the [collection] 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 . 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.
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.
Note again that the behaviour "cannot be guaranteed" and is only "on a best-effort basis".
The documentation of several methods of the Map interface say this:
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. 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.
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.
Debugging ConcurrentModificationException
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 . You must examine the stack-trace to determine which class of Collection threw the exception (a method of the class will have directly or indirectly thrown it), and for which Collection object. Then you must examine from where that object can be modified.
- The most common cause is modification of the Collection within an enhanced for loop over the Collection . Just because you do not see an Iterator object in your source code does not mean there is no Iterator there! Fortunately, one of the statements of the faulty for loop will usually be in the stack-trace, so tracking down the error is usually easy.
- A trickier case is when your code passes around references to the Collection object. Note that unmodifiable views of collections (such as produced by Collections.unmodifiableList() ) retain a reference to the modifiable collection, so iteration over an "unmodifiable" collection can throw the exception (the modification has been done elsewhere). Other views of your Collection , such as sub lists, Map entry sets and Map key sets also retain references to the original (modifiable) Collection . This can be a problem even for a thread-safe Collection , such as CopyOnWriteList ; do not assume that thread-safe (concurrent) collections can never throw the exception.
- Which operations can modify a Collection can be unexpected in some cases. For example, LinkedHashMap.get() modifies its collection.
- The hardest cases are when the exception is due to concurrent modification by multiple threads.
Programming to prevent concurrent modification errors
When possible, confine all references to a Collection object, so its is easier to prevent concurrent modifications. Make the Collection a private object or a local variable, and do not return references to the Collection or its iterators from methods. It is then much easier to examine all the places where the Collection can be modified. If the Collection is to be used by multiple threads, it is then practical to ensure that the threads access the Collection only with appropriate synchonization and locking.