ConcurrentModificationException in HashMap<Object,DateTime>

59 views Asked by At

I have the following code:

 Iterator<ggItem> iter = ggItemTimestampMap.keySet().iterator();
 ggItem gg;
 while (iter.hasNext()) {
        gg = iter.next();
        if (DateTime.now().isAfter(ggItemTimestampMap.get(gg).plusSeconds(10))) {
             Log.v("ggItem 10 second limit:", gg.toString());
             //If it hasn't been seen 10 seconds after its last timestamp. Remove it from the ArrayList and remove it from the ggItemTimeStampMap HashMap.
             ggItemTimestampMap.remove(gg); //TODO probable problem causer.
             removeggItemFromList(gg);
         }
 }

I get a ConcurrentModificationException error on the iter.next(); call and am uncertain why?

I realize you cannot both access a hashmap of object keys and timestamp values and modify it at the same time, but doesn't the iterator counteract that?

3

There are 3 answers

4
Blackbelt On

I get a concurrentModificationException error on the iter.next();

It's because you are iterating and removing from the same list at the same time. Since you are using an Iterator, to remove the item call

iter.remove();

From the documentation

Removes from the underlying collection the last element returned by the iterator

0
Denis Kulagin On

Use

iter.remove()

which removes element from the underlying collection, not from the iterator.

Actually, iterator is just a stateful pointer to the collection, which keeps internal state, e.g. link to a currently traversed element. Removing an element, invoking method on iterator provides separation of concerns and correct behaviour of the iterator, after element is removed.

0
Sergey Shustikov On

First of all you can change HashMap to ConcurrentHashMap

Secondary you may have try to synchronize iter on class or of object.

synchronized(this) // if not in static context 
{
    // synchronized body
}

synchronized(iter)
{
    // synchronized body
}

or use in method declaration

public synchronized void add(int value){
     this.count += value;
}


And this problem was explained :

// @see http://stackoverflow.com/questions/602636/concurrentmodificationexception-and-a-hashmap
Iterator it = map.entrySet().iterator();
while (it.hasNext())
{
   Entry item = it.next();
   map.remove(item.getKey());
}

Correct way :

// @see http://stackoverflow.com/questions/602636/concurrentmodificationexception-and-a-hashmap
   Iterator it = map.entrySet().iterator();
   while (it.hasNext())
   {
      Entry item = it.next();
      it.remove(item);
   }

For future troubles you need to know what the ConcurrentModificationException means :

This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.