In multithreaded Java environments, attempting to modify a collection while iterating over it using an iterator can lead to a ConcurrentModificationException
. This exception arises because the collection's internal state becomes inconsistent.
Here's an example illustrating the exception:
<code class="language-java">Exception in thread "main" java.util.ConcurrentModificationException at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:000) at java.base/java.util.ArrayList$Itr.next(ArrayList.java:000) at com.journaldev.ConcurrentModificationException.ConcurrentModificationExceptionExample.main(ConcurrentModificationExceptionExample.java:00)</code>
This exception occurs under these conditions:
modCount
) to detect modifications and throws the exception.Algorithm for Reproducing the Exception
This algorithm demonstrates how to trigger a ConcurrentModificationException
in Java:
ArrayList
.ArrayList
.list.iterator()
.ArrayList
(e.g., add or remove elements).ConcurrentModificationException
is thrown when the iterator detects the modification.Code Example: Triggering the Exception
<code class="language-java">import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ConcurrentModificationExample { public static void main(String[] args) { List<integer> myList = new ArrayList<>(); myList.add(1); myList.add(2); myList.add(3); Iterator<integer> iterator = myList.iterator(); while (iterator.hasNext()) { Integer value = iterator.next(); System.out.println("Value: " + value); if (value == 2) { myList.remove(value); // Modification during iteration! } } } }</integer></integer></code>
This code will throw a ConcurrentModificationException
because myList.remove(value)
modifies the list while the iterator is traversing it.
Safe Modification Techniques
To avoid this exception, use these approaches:
Iterator.remove()
: Use the iterator.remove()
method to remove elements during iteration. This method is safe because it's designed to work with the iterator's internal state.
Copy the List: Create a copy of the list before iterating and modify the copy.
Use Concurrent Collections: For concurrent modification scenarios, use thread-safe collections like CopyOnWriteArrayList
or ConcurrentHashMap
.
Synchronized Block: Enclose the iteration and modification within a synchronized block to ensure thread safety.
Example: Safe Removal using Iterator.remove()
<code class="language-java">import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class SafeRemovalExample { public static void main(String[] args) { List<integer> myList = new ArrayList<>(); myList.add(1); myList.add(2); myList.add(3); Iterator<integer> iterator = myList.iterator(); while (iterator.hasNext()) { Integer value = iterator.next(); System.out.println("Value: " + value); if (value == 2) { iterator.remove(); // Safe removal using iterator.remove() } } System.out.println(myList); } }</integer></integer></code>
This revised code safely removes the element without throwing the exception. Remember to choose the appropriate technique based on your specific needs and concurrency requirements. Using concurrent collections is generally preferred for multithreaded scenarios.
The above is the detailed content of ConcurrentModificationException while using Iterator in Java. For more information, please follow other related articles on the PHP Chinese website!