Java.util.ConcurrentModificationException Examples And Resolution

When you operate java collection object use iterator, you may always meet java.util.ConcurrentModificationException error. It is because the java collection object has been changed while others still use iterator.next() to loop in it. Below is just an example code which can throw concurrent modification exception.

Concurrent Modification Exception Examples

When you execute below java code, you may see ConcurrentModificationException like below picture.

java.util.ConcurrentModificationException output

  1. ConcurrentModificationException occurred after remove one object in java List.
    	public static void testListCMException()
    	{
    		/* Initiate a ArrayList object. */
    		List<String> phoneList = new ArrayList<String>();
    		
    		phoneList.add("Apple");
    		phoneList.add("Google");
    		phoneList.add("Microsoft");
    		phoneList.add("Huawei");
    		phoneList.add("Xiao Mi");
    		phoneList.add("Vivo");
    
    		/* Get the object's iterator. */
    		Iterator<String> it = phoneList.iterator();
    		
    		/* Iterate the object. */
    		while(it.hasNext())
    		{
    			String phone = it.next();
    			
    			System.out.println("Current phone is " + phone);
    			
    			/* Remove the object.*/
    			if(phone.equalsIgnoreCase("microsoft"))
    			{
    				/* ArrayList changed after remove, so it.next() will throw ConcurrentModificationException. */
    				phoneList.remove(phone);
    			}
    		}
    	}
  2. ConcurrentModificationException occurred after add another key value pair in java Map.
    	public static void testMapCMException()
    	{
    		/* Initiate a Map object. */
    		Map<String, String> osMap = new HashMap<String, String>();
    		
    		osMap.put("android", "android");
    		osMap.put("ios", "ios");
    		osMap.put("macos", "macos");
    		osMap.put("windows", "windows");
    		osMap.put("linux", "linux");
    		osMap.put("unix", "unix");
    
    
    		/* Get the map object's values collection. */
    		Collection<String> vCollection = osMap.values();
    		
    		/* Get vCollection' iterator. */
    		Iterator<String> it = osMap.values().iterator();
    		
    		/* Iterate vCollection. */
    		while(it.hasNext())
    		{
    			String os = it.next();
    			
    			System.out.println("OS is " + os);
    			
    			/* Add new object in the map.*/
    			if(os.equalsIgnoreCase("ios"))
    			{
    				/* After add, collection changed, so it.next() will throw ConcurrentModificationException. */
    				osMap.put("redhat", "redhat");
    			}
    		}
    	}
  3. ConcurrentModificationException occurred with subList after original List change.
    	public void testSubListCMException()
    	{
    		List<String> fruitList = new ArrayList<>();
    		
    		fruitList.add("Apple"); 
    		fruitList.add("Orange");
    		fruitList.add("Banana"); 
    		fruitList.add("Pear"); 
    		fruitList.add("hawthorn"); 
    		
    		
    		List<String> subFruitList = fruitList.subList(0, 2);
    		
    		System.out.println(fruitList + " , " + subFruitList);
    		
    		fruitList.set(1, "Watermelon ");
    		
    		System.out.println(fruitList + " , " + subFruitList);
    		
    		// Add another fruit.
    		fruitList.add("cherry");
    		
    		/* Remove comment below code, get the sub list again after original list change 
    		can avoid ConcurrentModificationException. */
    		//subFruitList = fruitList.subList(0, 2);
    		
    		//Below code will throw ConcurrentModificationException, because original list fruitList changed.
    		System.out.println(fruitList +" , "+subFruitList);
    	}

How To Fix ConcurrentModificationException 

Jdk1.5 or higher provide Concurrent Collection classes that you can use to avoid this exception. CopyOnWriteArrayList and ConcurrentHashMap are two example class.

  1. CopyOnWriteArrayList Example.
    	public static void testListWithoutCMException()
    	{
    		/* Initiate a CopyOnWriteArrayList object. */
    		List<String> languageList = new CopyOnWriteArrayList<String>();
    		
    		languageList.add("java");
    		languageList.add("c++");
    		languageList.add("python");
    		languageList.add("perl");
    		languageList.add("javascript");
    		languageList.add("go");
    		
    		System.out.println("Strings before remove. ");
    		/* Print each string in the list before remove.*/
    		for(String codingLanguage : languageList)
    		{
    			System.out.println(codingLanguage);
    		}
    		
    
    		/* Get the object's iterator. */
    		Iterator<String> it = languageList.iterator();
    		
    		/* Iterate the object. */
    		while(it.hasNext())
    		{
    			String codingLanguage = it.next();
    			
    			/* Remove the object.*/
    			if(codingLanguage.equalsIgnoreCase("perl"))
    			{
    				languageList.remove(codingLanguage);
    				languageList.add("scala");
    			}
    		}
    		
    		System.out.println("");
    		System.out.println("Strings after remove. ");
    		/* Print each string in the list after remove.*/
    		for(String codingLanguage : languageList)
    		{
    			System.out.println(codingLanguage);
    		}
    	}

    Output
    CopyOnWriteArrayList output

  2. ConcurrentHashMap Example.
    	public static void testMapWithoutCMException()
    	{
    		/* Initiate a ConcurrentHashMap object. */
    		Map<String, String> dbMap = new ConcurrentHashMap<String, String>();
    		
    		dbMap.put("oracle", "oracle");
    		dbMap.put("mysql", "mysql");
    		dbMap.put("db2", "db2");
    		dbMap.put("sql server", "sql server");
    		dbMap.put("hadoop", "hadoop");
    		dbMap.put("mongodb", "mongodb");
    
    
    		/* Get the map object's values collection. */
    		Collection<String> vCollection = dbMap.values();
    		
    		/* Get vCollection' iterator. */
    		Iterator<String> it = dbMap.values().iterator();
    		
    		/* Iterate vCollection. */
    		while(it.hasNext())
    		{
    			String db = it.next();
    			
    			/* Add new object in the map.*/
    			if(db.equalsIgnoreCase("db2"))
    			{
    				dbMap.put("Big Table", "Big Table");
    			}
    		}
    		
    		
    		System.out.println("Map data after add. ");
    		
    		Set<String> dbKeySet = dbMap.keySet();
    		
    		Iterator<String> dbKeySetIt = dbKeySet.iterator();
    		
    		while(dbKeySetIt.hasNext())
    		{
    			String db = dbKeySetIt.next();
    			System.out.println("Database is " + db);
    		}
    	}

    Output
    ConcurrentHashMap example output

  3. Fix original List changed caused subList ConcurrentModificationException.
    This is very simple, you just need to get the subList again to avoid this.
    get sub list again after original list change to avoid concurrentmodificationException
  4. Use for loop instead of iterator.
    	public void testListWithoutCMExceptionUseForLoop()
    	{
    		/* Initiate a Arraylist object. */
    		List<String> ballList = new ArrayList<String>();
    		
    		ballList.add("football");
    		ballList.add("basketball");
    		ballList.add("volleyball");
    		
    		System.out.println("List strings before remove. ");
    		/* Print each string in the list before remove.*/
    		for(String ball : ballList)
    		{
    			System.out.println(ball);
    		}
    		
    		
    		int size = ballList.size();
    		for(int i = 0;i<size;i++)
    		{
    			String ball = ballList.get(i);
    			if("football".equalsIgnoreCase(ball))
    			{
    				ballList.add("table tennis");
    				
    				// After add, should recalculate the size.
    				size = ballList.size();
    			}
    			
    			if("basketball".equalsIgnoreCase(ball))
    			{
    				ballList.remove(ball);
    				
    				// After remove, should recalculate the size and i--.
    				i--;
    				size = ballList.size();
    			}
    		}
    		
    		
    		System.out.println("");
    		System.out.println("Strings after remove. ");
    		/* Print each string in the list after remove.*/
    		for(String ball : ballList)
    		{
    			System.out.println(ball);
    		}
    	}

Download “Java.util.ConcurrentModificationException-Examples-And-Resolution.zip” Java.util_.ConcurrentModificationException-Examples-And-Resolution.zip – Downloaded 50 times – 2 KB

(Visited 794 times, 1 visits today)
READ :   Java String Example

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.