Reputation: 10662
I get a ConcurrentModificationException
even though I made all the methods of the whole program synchronized (including static methods and the main
method).
I don't have hidden iterators.
Upvotes: 0
Views: 273
Reputation: 3894
You get this exception when you're iterating over a collection and during this you remove an entry from this collection.
e.g.
Collection<Object> objects = new ArrayList<Objects>(Arrays.asList("a","b"));
for (Object o : objects) {
objects.remove(o); //throws exception
}
You must add the ones you want to remove to another collection and remove them after your finished iterating over the list. Otherwise, you iterate over the objects collection via it's iterator() and call remove() on the current iterator.
Upvotes: 3
Reputation: 41127
The javadoc for ConcurrentModificationException contains the answer:
Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.
The way to fix it is to not do that.
I.e., (as others have noted) if you need to simultaneously iterate and modify, use the methods supplied by the iterator rather than modifying the collection directly.
Upvotes: 1
Reputation: 346260
ConcurrentModificationException
can be caused by the same thread manipulating a collection while iterating over itIterator.remove()
or ListIterator.add()
methodsUpvotes: 6
Reputation: 4164
A synchronized method places a lock on the object instance it's running with.
If objects A and B access the same collection, it doesn't matter if A#doStuff and B#doStuff are synchronized - they can still execute concurrently.
To lock the collection, you probably want a lock on the collection itself: synchronized(collection) in the method bodies, or a Java 5 mutex (better).
(that and the fact that you can have ConcurrentModificationException even in a single thread as others have pointed out).
Upvotes: 1
Reputation: 112356
Well, to start with, if you're seeing it, it's possible: if the bird book and the bird disagree, believe the bird.
Now, how can it happen? Hard to say exactly without seeing your code, but the exception stacktrace will point to the place it happened; what do you see around that?
In general, it's going to happen when you have, obviously, concurrent accesses. When you find the place in which it's happening, ask yourself what threads could be getting there.
Upvotes: 3
Reputation: 40256
If you run this
List<Object> list = new ArrayList<Object>();
for(Object obj : list)
list.remove(obj);
You will get a comodification. You cannot alter a collection while iterating over it without using the appropriate functions.
This can be resolved using the following:
List<Object> list = new ArrayList<Object>();
for(Iterator<Object> itr = list.iterator(); itr.hasNext();)
itr.remove();
Upvotes: 3
Reputation: 8204
ConcurrentModificationException is NOT related to synchronization.
It's related to modifying a collection while iterating through it. As Lie Ryan points out, a full stack trace would help us point out how you got it.
Generally, to fix this, you must not modify the collection itself while iterating through it.
Upvotes: 3