Reputation: 99
I have been having a lot of trouble with the Concurrent Modification Exception error. With the help of the community I managed to fix my last error, however I think this error is more puzzling.
I am now getting a concurrent modification error while painting, I am worried that this error occurs in the paint function itself. Unlike my last error I am nto removing an entity, in that case I completely understood what was going on just not how to fix it, this error on the other hand I do not understand.
TowerItr = activeTowers.iterator();
while (TowerItr.hasNext()) {
try {
theTower = (ArcherTower) TowerItr.next();
g.drawImage(tower, theTower.y * Map.blockSize, theTower.x * Map.blockSize, this);
} catch (ConcurrentModificationException e) {
}
}
The line that throws the exception is this one: theTower = (ArcherTower) TowerItr.next();
Upvotes: 0
Views: 1762
Reputation: 2360
Carrying on from what our esteemed members have suggested:
1) This error is generally seen when the List
is being modified after an Iterator
has been extracted.
2) I am looking at your code and it seems alright except this
being used in the drawImage()
method. This may potentially be altering your List
because This
has direct access to class members / class variables
.
3) This can also happen if multiple threads are accessing the List
concurrently. And one of the threads may be trying to alter your List
from some other method which share the same instance of the List
. I am saying some other method because concurrent read access should not create trouble if multiple threads were accessing this method
.
Note: Please all posible code and Stake trace to debug exact problem.
Upvotes: 0
Reputation: 17707
There are always two sides to a ConcurrentModificationException (CME), and only one side reports the error.
In this case, your code looks perfectly fine. You are looping through the members of the activeTowers.
The stack trace will show you nothing that you don't already know.... you have a CME.
What you need to find out is where you are adding/removing data from the activeTowers collection.
In many cases, there are reasonably easy fixes. A probable fix is to synchronize the access to the activeTowers array in every place it is used. This may be quite hard to do.
Another option is to use a collection from the java.util.concurrent.* package, and to use the toArray(...) methods to get a snapshot of the collection, and then you can iterate that snapshot in your while loop.
// activeTower must be something from java.util.concurrent.*
for (ArcherTower theTower : activeTower.toArray(new ArcherTower[0]) {
g.drawImage(tower, theTower.y * Map.blockSize, theTower.x * Map.blockSize, this);
}
I should add that if you use a java.util.concurrent.* collection, then the iterator() will return a 'stable' iterator too (will not throw CME, and may (or may not) reflect changes in the collection)
Bottom line is that a CME only tells you half the story.... and only your code will tell you the rest....
Upvotes: 4