1. Introduction
In this article, we'll take a look at the ConcurrentModificationException class.
First, we'll give an explanation how it works, and then prove it by using a test for triggering it.
Finally, we'll try out some workarounds by using practical examples.
1. ArrayList remove() method Example
Now, let's see an example of removing elements from ArrayList while looping using for()loop and ArrayList.remove() method, which is wrong, and the program will throw ConcurrentModificationExcetpion upon execution.import java.util.ArrayList; import java.util.List; /* * Java Program to remove an element while iterating over ArrayList */ public class Main { public static void main(String[] args) throws Exception { List<String> loans = new ArrayList<>(); loans.add("personal loan"); loans.add("home loan"); loans.add("auto loan"); loans.add("credit line loan"); loans.add("mortgage loan"); loans.add("gold loan"); // printing ArrayList before removing any element System.out.println(loans); // removing element using ArrayList's remove method during iteration // This will throw ConcurrentModification for (String loan : loans) { if (loan.equals("personal loan")) { loans.remove(loan); } } // printing ArrayList after removing an element System.out.println(loans); } }
Output
Exception in thread "main" [personal loan, home loan, auto loan, credit line loan, mortgage loan, gold loan]
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at Main.main(Main.java:26)
Some of you may wonder that we are getting ConcurrentModificationException because we are not using the Iterator, but that's not true, even if you use Iterator you will get java.util.ConcurrentModificationException as long as you will use ArrayList's remove() method for removing element while iterating as shown in the following example:
Iterator<String> itr = loans.iterator(); while (itr.hasNext()) { String loan = itr.next(); if (loan.equals("personal loan")) { loans.remove(loan); } }
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at Main.main(Main.java:29)
In order to fix the above code, you just need to remove the loans.remove(loan) with the itr.remove()method, which is explained in the next example. Though, if you want to know more about Iterator and in general Java Collection Framework, which can feel daunting sometimes, I suggest you go throughJava Fundamentals: Collectionscourse on Pluralsight.
It's a perfect course to both learn and master the Java Collection framework and I highly recommend you to join this course.
Solving ConcurrentModificationException in ArrayList
Here is the Java program to demonstrate one scenario where you get the ConcurrentModificationException even if just one thread is modifying the ArrayList. In this example, we are looping over ArrayList using advanced for loop and removing selected elements, but because we are using ArrayList's remove() method.import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; /** * Java Program to demonstrate how to deal with * ConcurrentModificationException. * Unlike the name suggests, this error can come even if only * one thread is modifying the collection e.g. List. * It happens when you modify collection * while iterating over it e.g. adding new element or removing elements. * * If you want to remove elements while traversing list then * make sure you use Iterator's remove() method or not ArrayList's remove() * method() to avoid ConcurrentModificationExcetpion. * * @author WINDOWS 8 * */ public class ConcurrentModExceptionDemo{ public static void main(String args[]) { List<String> listOfPhones = new ArrayList<String>(Arrays.asList( "iPhone 6S", "iPhone 6", "iPhone 5", "Samsung Galaxy 4", "Lumia Nokia")); System.out.println("list of phones: " + listOfPhones); // Iterating and removing objects from list // This is wrong way, will throw ConcurrentModificationException for(String phone : listOfPhones){ if(phone.startsWith("iPhone")){ // listOfPhones.remove(phone); // will throw exception } } // The Right way, iterating elements using Iterator's remove() method for(Iterator<String> itr = listOfPhones.iterator(); itr.hasNext();){ String phone = itr.next(); if(phone.startsWith("iPhone")){ // listOfPhones.remove(phone); // wrong again itr.remove(); // right call } } System.out.println("list after removal: " + listOfPhones); } } Output : list of phones: [iPhone 6S, iPhone 6, iPhone 5, Samsung Galaxy 4, Lumia Nokia] list after removal: [Samsung Galaxy 4, Lumia Nokia]
If you uncomment the commented code in the first loop and second loop, you will get the following exception:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at dto.ReverseArrayInPlace.main(ReverseArrayInPlace.java:28)
because we are using ArrayList's remove() method. In the second example, we have used theremove() method of Iterator and that's why we are successfully able to delete selected elements from the ArrayList without ConcurrentModificationException.
Here is a summary of important points about solving ConcurrentModificationException while looping over ArrayList in Java :
That's all about how to deal with ConcurrentModificationException in Java. The biggest thing to learn and remember is that this error can come even if you have just one thread modifying collection e.g. removing elements while looping over the list.
Related troubleshooting guides
Here are some handy Java tips to solve some common errors and exceptions in Java:
- How to deal withjava.lang.NoClassDefFoundError: org/apache/xmlbeans/XmlObject? (solution)
- How to solve "could not create the Java virtual machine" error in Java? (solution)
- Fixing java.lang.unsupportedclassversionerror unsupported major.minor version 50.0 (solution)
- java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory error (solution)
- How to solvejava.lang.ClassNotFoundException: com.mysql.jdbc.Driver error? (hint)
- How to solvejava.lang.classnotfoundexception oracle.jdbc.driver.oracledriver? (solution)
- java.lang.ClassNotFoundException : org.Springframework.
Web.Context.ContextLoaderListener (solution) - How to fix 'javac' is not recognized as an internal or external command(solution)
- How to fix Caused By: java.lang.NoClassDefFoundError: org/apache/log4j/Logger (solution)
- How to solve java.lang.OutOfMemoryError: Java Heap Space in Eclipse, Tomcat? (solution)