0

I am getting ConcurrentModificationException when executing the following code:

    public void refreshAvailableCaseSettings() throws Exception {
        //getAvailableCases() returns reference to the instance variable
        LinkedHashMap<Integer, CaseSetting> cases = getAvailableCases();
        /* java.util.ConcurrentModificationException even after trying entryset()
        for(Map.Entry<Integer, CaseSetting> entry : cases.entrySet()){
            entry.getValue().refresh(false);
        }
        */

        // java.util.ConcurrentModificationException
        Iterator casesIterator = cases.values().iterator();
        while (casesIterator.hasNext()) {
            CaseSetting caseSetting = casesIterator.next();
            //refresh() updates caseSetting state by getting setting info from DB
            caseSetting.refresh(false);
        }
    }

Error:

   java.util.ConcurrentModificationException
    at java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:719)
    at java.util.LinkedHashMap$LinkedEntryIterator.next(LinkedHashMap.java:752)
    at java.util.LinkedHashMap$LinkedEntryIterator.next(LinkedHashMap.java:750)

I am not modifying the map by adding or removing elements. Please help me to understand the issue here.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
javaProf
  • 31
  • 1
  • 5
  • Where does `getAvailableCases();` get its return value? Is it code you wrote? It looks like `getAvailableCases();` is returning a reference to a map that is modified from somewhere inside that code. – Jerry Jeremiah Apr 23 '20 at 04:39
  • can you also post the CaseSetting class.. – Shoaeb Apr 23 '20 at 04:52
  • @JerryJeremiah: You are correct getAvailableCases() returns reference to the instance variable. – javaProf Apr 23 '20 at 13:46
  • I wouldn't expect refresh to change the collection - I would think it just updates the elements. But if getAvailableCases() returns a reference to a map then some other thread might be adding items to the map while you are trying to refresh it. The only way you would know is if its all your code. – Jerry Jeremiah Apr 23 '20 at 23:51

2 Answers2

1

The general contract for using iterators is this:

While an iterator over a collection is in progress, the underlying collection must not be modified.

You can do whatever you want on the elements of the collection, but you must not touch the collection itself.

You are getting a ConcurrentModificationException because a part of your code within the while loop does exactly that - it changes the underlying collection.

A standard approach is to either (a) create a new copy of the collection and iterate over this read-only copy, or (b) put the changes into a separate collection.

jurez
  • 4,436
  • 2
  • 12
  • 20
0

What refresh function does ? According to my understanding you are getting these only because you are modifided HashMap while iterating it, I used to get these error when I used to put something in map, means size was increasing.

Also you need to put everything in question, like CaseSetting class

Rushikesh
  • 129
  • 1
  • 4