Avoid ConcurrentModificationException in multi-threaded

In this article, we will learn about the Avoid ConcurrentModificationException in multi-threaded.

You can convert the list to an array and then iterate over the array. This approach works well for small to medium sized lists, but if the list is large it will severely affect performance.
You can lock the list during iteration by placing it in a synchronized block. This approach is not recommended because it eliminates the benefits of multithreading.
you can use the ConcurrentHashMap and CopyOnWriteArrayList classes If you are using JDK1.5 or higher. This is the recommended approach to avoid simultaneous change exceptions.

Avoid ConcurrentModificationException in a single-threaded environment

You can use the iterator remove() function to remove the object from the underlying collection object. In this case, however, you can delete the same object and no other object from the list.

Example

package com.HandyOpnion.Concurrent_Modification_Exception;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.OnWriteArrayList;

public class AvoidConcurrentModificationException {

	public static void main(String[] args) {

		List<String> myList = new OnWriteArrayList<String>();

		myList.add("1");
		myList.add("2");
		myList.add("3");
		myList.add("4");
		myList.add("5");

		Iterator<String> it = myList.iterator();
		while (it.hasNext()) {
			String value = it.next();
			System.out.println("List Value:" + value);
			if (value.equals("3")) {
				myList.remove("4");
				myList.add("6");
				myList.add("7");
			}
		}
		System.out.println("List Size:" + myList.size());

		Map<String, String> myMap = new ConcurrentHashMap<String, String>();
		myMap.put("1", "1");
		myMap.put("2", "2");
		myMap.put("3", "3");

		Iterator<String> 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("3");
				myMap.put("4", "4");
				myMap.put("5", "5");
			}
		}

		System.out.println("Map Size:" + myMap.size());
	}

}

Output

List Value:1
List Value:2
List Value:3
List Value:4
List Value:5
List Size:6
Map Value:1
Map Value:2
Map Value:4
Map Value:5
Map Size:4

From the example above it becomes clear that

  • Concurrent Collection classes can be changed safely; they do not throw a ConcurrentModificationException.
  • In the case of CopyOnWriteArrayList, the iterator does not support list changes and works with the original list.
  • With ConcurrentHashMap, the behavior is not always the same.
if(key.equals("1")){
	myMap.remove("3");}

Output

Map Value:1
Map Value:null
Map Value:4
Map Value:2
Map Size:4

The new object is added with key “4” but not with the next added object with key “5”.

Now if the condition changes to below.

if(key.equals("3")){
	myMap.remove("2");}

Output

Map Value:1
Map Value:3
Map Value:null
Map Size:4

So if you are using ConcurrentHashMap, avoid adding new objects as they can be processed depending on the key ring. Note that the same program may print different values in your system because the HashMap keyset has not been ordered.

Thats all about the how to Avoid ConcurrentModificationException in multi-threaded.

Next Article

1. Use for loop to avoid java.util.ConcurrentModificationException

Please share this post:
Posts created 54

Ask a Question

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

Related Posts

Begin typing your search term above and press enter to search. Press ESC to cancel.

%d bloggers like this: