Every Java developer encountered ConcurrentModificationException in Java his/her life specially in early development days. How to avoid ConcurrentModificationException, how to overcome this exception either in multi-threaded or single-threaded environment.
1. overview of ConcurrentModificationException in Java?
Well, you must encountered this exception in developer life. java.util.ConcurrentModificationException
in his/her life is usuall . You must have several questions in you mind: what is java.util.ConcurrentModificationException
in Java? How to avoid java.util.ConcurrentModificationException
? how to overcome java.util.ConcurrentModificationException
exception either in multi-threaded or single-threaded environment.
For understanding concurrentModificationException you must know Fail-safe Vs Fail-fast iterator?
2. Why java.util.ConcurrentModificationException in Java?
- if two thread trying to modify one collection at same time. e.g. if one thread iterating and another removing.
- even in the same thread, remove List.remove() method while iterating using advance-for each loop.
- if trying to modify structure i.e. adding element to and removing element from fail-fast collection.
3. When to Throws java.util.ConcurrentModificationException
If you change the structure of fail-fast collection while iterating, it throws ConcurrentModificationException
which I tried to demonstrate below. In below code base demonstrate while removing , but if you try to add it throws ConcurrentModificationException
. internally it check counter flag is any modifying structure or not , if yes throws exception.
ConcurrentModificationExceptionExample.java
package com.mysoftkey.exception; import java.util.ArrayList; import java.util.List; /** * @author ranjeet Jha * */ public class ConcurrentModificationExceptionExample { /** * @param args */ public static void main(String[] args) { ListframeworkList = new ArrayList (); // add values. frameworkList.add("Spring"); frameworkList.add("Hibernate"); frameworkList.add("Struts"); for (String val : frameworkList) { if ("Struts".equals(val)) { frameworkList.remove(val); } } // calling List's remove() method will throws java.util.ConcurrentModificationException while iterating Iterator it = frameworkList.iterator(); while (it.hasNext()) { String val = it.next(); if ("Struts".equals(val)) { frameworkList.remove(val); } } }
Console output with ConcurrentModificationException
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.mysoftkey.exception.ConcurrentModificationExceptionDemo.main(ConcurrentModificationExceptionDemo.java:26)
NOTE: If you want to go into more details of , how Iterator checks for the structure modification, You can lookinto java.util.AbstractList
class where you can find an int variable modCount
. modCount
is used for the number of times list size has been changed. modCount value is used in every next()
call to check for any modifications in a function checkForComodification()
.
3. How to use iterator.remove() method to avoid ConcurrentModificationException?
Either you use fail-safe collection to avoid ConcurrentModificationException
or use Concurrent collection: ConcurrentHasMap, CopyOnArrayList, ListIterator. If you want to know about what is fail-fast and fail-safe collection, you can visit my post.
package com.mysoftkey.exception; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * @author ranjeet Jha * */ public class ConcurrentModificationExceptionDemo { /** * @param args */ public static void main(String[] args) { ListframeworkList = new ArrayList (); // following code will not throws ConcurrentModificationException Iterator itr = frameworkList.iterator(); while (itr.hasNext()) { String val = itr.next(); if ("Struts".equals(val)) { // Use Iterator's remove() method will throws java.util.ConcurrentModificationException itr.remove(); } } } }
4. How to avoid in multi-threaded environment?
Everyone in java must have upgraded at least jdk 5, if so then use concurrent collections class.
- use
ConcurrentHashMap
andCopyOnWriteArrayList
classes, if using jdk 5 or higher version. - Use conversion of List to arrays, if collection size is small probably 100 or less. In larger collection impact performance.
- You can use synchronized block, but this will not help much in multi-threaded environment.
Multi-threadedIteratorExample.java
package com.mysoftkey.exception; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; /** * @author ranjeet * */ public class ConcurrentModificationExceptionExample { public static void main(String[] args) { System.out.println("=============== ConcurrentHashMap =========================="); ListframeworkList = new CopyOnWriteArrayList (); // add values. frameworkList.add("Spring"); frameworkList.add("Hibernate"); frameworkList.add("Struts"); Iterator it = frameworkList.iterator(); while(it.hasNext()){ String value = it.next(); System.out.println("List Value:"+value); if(value.equals("3")){ frameworkList.remove("Struts"); frameworkList.add("WebServices"); } } System.out.println("List Size:" + frameworkList.size()); System.out.println("=============== ConcurrentHashMap =========================="); Map myMap = new ConcurrentHashMap (); myMap.put("1", "One"); myMap.put("2", "Two"); Iterator it1 = myMap.keySet().iterator(); while (it1.hasNext()) { String key = it1.next(); System.out.println("Map Value:" + myMap.get(key)); if (key.equals("1")) { myMap.remove("1"); myMap.put("100", "Hundres"); } } System.out.println("Map Size:" + myMap.size()); } }
List Value:Spring List Value:Hibernate List Value:Struts List Size:3 =============== ConcurrentHashMap ========================== Map Value:One Map Value:Two Map Size:2
5. How to avoid ConcurrentModificationException in single-threaded Environment
if you trying to remove element from List while iterating.
Use Iterator’s remove() method if removing
// following code will not throws ConcurrentModificationException Iteratoritr = frameworkList.iterator(); while (itr.hasNext()) { String val = itr.next(); if ("Struts".equals(val)) { // calling Iterator's remove() method will throws java.util.ConcurrentModificationException itr.remove(); } }
Use classic/typical for loop while conditional remove.
for (int i = 0; i < frameworkList.size(); i++) { String val = frameworkList.get(i); System.out.println(val); if ("Struts".equals(val)) { frameworkList.remove(val); } }
6. Similar Posts
7. Reference
for more details visit Oracle Java Site
I hope, you enjoyed this post about ConcurrentModificationException in java. You can visit Core Java tutorial for more example blog post.
Write your comment if would like this post.