What is ConcurrentModificationException in Java?

Connect with

Oracle JavaEvery java developer must have encountered java.util.ConcurrentModificationException in his/her life specially in early development days . You must have several questions in you mind: what is code>ConcurrentModificationException in Java? How to avoid ConcurrentModificationException? how to overcome ConcurrentModificationException exception either in multi-threaded or single-threaded environment.

1. Why java.util.ConcurrentModificationException?

  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.

2. 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 MultiThreadedIteratorExample {
	 
 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);
  }
}

Similar Post

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

Write your comment if would like this post.


Connect with

Leave a Reply

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