What is ConcurrentModificationException in Java?

Connect with

What is ConcurrentModificationException in Java?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?

  1. if two thread trying to modify one collection at same time. e.g. if one thread iterating and another removing.
  2. even in the same thread, remove List.remove() method while iterating using advance-for each loop.
  3. 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) {

	List frameworkList = 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) {

	List frameworkList = 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.

  1. use ConcurrentHashMap and CopyOnWriteArrayList classes, if using jdk 5 or higher version.
  2. Use conversion of List to arrays, if collection size is small probably 100 or less. In larger collection impact performance.
  3. 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 ==========================");
	List frameworkList = 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
 Iterator itr = 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

  1. Fail-safe Vs Fail-fast iterator?
  2. How to delete element from List
  3. How to remove entry from Hashmap

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.


Connect with

Leave a Comment

Your email address will not be published. Required fields are marked *