Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to debug ConcurrentModificationException? [duplicate]

I encountered ConcurrentModificationException and by looking at it I can't see the reason why it's happening; the area throwing the exception and all the places modifying the collection are surrounded by

synchronized (this.locks.get(id)) {
  ...
} // locks is a HashMap<String, Object>;

I tried to catch the the pesky thread but all I could nail (by setting a breakpoint in the exception) is that the throwing thread owns the monitor while the other thread (there are two threads in the program) sleeps.


How should I proceed? What do you usually do when you encounter similar threading issues?

like image 745
Dani Avatar asked May 08 '09 14:05

Dani


People also ask

How do you resolve ConcurrentModificationException?

How do you fix Java's ConcurrentModificationException? There are two basic approaches: Do not make any changes to a collection while an Iterator loops through it. If you can't stop the underlying collection from being modified during iteration, create a clone of the target data structure and iterate through the clone.

Does HashMap throw ConcurrentModificationException?

Since Iterator of HashMap is fail-fast it will throw ConcurrentModificationException if you try to remove entry using Map.

Who throws ConcurrentModificationException?

The ConcurrentModificationException generally occurs when working with Java Collections. The Collection classes in Java are very fail-fast and if they are attempted to be modified while a thread is iterating over it, a ConcurrentModificationException is thrown.


2 Answers

It may have nothing to do with the synchronization block. ConcurrentModificationExceptions often occur when you're modifying a collection while you are iterating over its elements.

List<String> messages = ...;
for (String message : messages) {
    // Prone to ConcurrentModificationException
    messages.add("A COMPLETELY NEW MESSAGE");
}
like image 98
Adam Paynter Avatar answered Sep 21 '22 20:09

Adam Paynter


Similar to a previous post, you can get the same issue if you delete an entry. e.g.

for(String message : messages) {
  if (condition(message))
     messages.remove(message);
}

Another common example is cleaning up a Map.

This particular problem can be resolved using an Iterator explicitly.

for(Iterator<String> iter = messages.iterator(); iter.hasNext();) {
   String message = iter.next();
   if (condition(message))
       iter.remove(); // doesn't cause a ConcurrentModificationException 
}
like image 25
Peter Lawrey Avatar answered Sep 17 '22 20:09

Peter Lawrey