Resolve ConcurrentModificationException
This tutorial gives details on “ConcurrentModificationException” and how to avoid it. As per Javadoc, “ConcurrentModificationException” may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible. An example, it is not generally permissible for one thread to modify a Collection while another thread is iterating over it.
Let’s see things in action.
- Create class “DemoArray.java”
- Create a List “techList”
- Add values to techList and iterate
- While iterating modify (add/remove) elements from techList
- We get ConcurrentModificationException because its internal modCount was alter.
- Now comment line 12 and uncomment line 15 and re-run program.
package com.ms; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; public class DemoArrayList { public static void main(String[] args) { // Comment out below code to avoid ConcurrentModificationException List<String> techList = new ArrayList<>(); // Uncomment below code to avoid ConcurrentModificationException // List<String> techList = new CopyOnWriteArrayList<>(); techList.add("JAVA"); techList.add("J2EE"); techList.add("Spring"); techList.add("Struts"); techList.add("Endeca"); Iterator<String> techIterator = techList.iterator(); // Add or remove operations to technologies List while performing hasNext() while (techIterator.hasNext()) { System.out.println("Tech list: " + techList); String techString = techIterator.next(); // Below statement causes ConcurrentModificationException System.out.println(techString); if (techString.equals("JAVA")){ techList.remove("J2EE"); } if (techString.equals("Spring")){ techList.add("Spring AOP"); } } } }
What triggered “java.util.ConcurrentModificationException”?
During the execution of code modCount was changed.
Error:
Tech list: [JAVA, J2EE, Spring, Struts, Endeca] JAVA Tech list: [JAVA, Spring, Struts, Endeca] Exception in thread "main" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(Unknown Source) at java.util.ArrayList$Itr.next(Unknown Source) at com.ms.DemoArrayList.main(DemoArrayList.java:28)
Resolving java.util.ConcurrentModificationException:
Using “CopyOnWriteArrayList” instead of “ArrayList” will resolve it. As per Javadoc, A thread-safe variant of ArrayList in which all mutative operations (add, set, and so on) are implemented by making a fresh copy of the underlying array. It creates ReentrantLock on object.
ReentrantLock is a concrete implementation of Lock interface provided in Java concurrency package from Java 1.5 onwards. As per Javadoc, ReentrantLock is mutual exclusive lock, similar to implicit locking provided by synchronized keyword in Java, with extended feature like fairness, which can be used to provide lock to longest waiting thread.