I'm using an iterator to loop over a collection as follows:
Iterator<Entity> entityItr = entityList.iterator();
while (entityItr.hasNext())
{
Entity curr = entityItr.next();
for (Component c : curr.getComponents())
{
if (c instanceof PlayerControlled)
{
((PlayerControlled) c).pollKeyboard();
}
}
}
However on the following line I get a ConcurrentModificationException
Entity curr = entityItr.next();
Why is this happening when I'm not altering anything?
Many thanks
Edit - stack trace:
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at cw.systems.Input.checkInputs(Input.java:31)
at cw.systems.Input.begin(Input.java:21)
at cw.misc.Game.render(Game.java:73)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:207)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114)
You must be modifying the list either:
pollKeyboard
method, without using theadd
orremove
methods on the iterator; orTherefore your exception is the expected behaviour. From the docs, if you have a single thread iterating the list:
and if multiple threads uses the list at one time:
Solution:
If only one thread accesses the list, make sure you use the
entityItr.remove
oradd
methods to modify the list.For the multi-threaded case you can use
Collections.synchronizedList
if you do not have a locking object available.First store a single central reference to your list as:
And then access it (with all readers and writers) as:
There are other ways to sync multi-threaded access, including copying the list to an array (inside a sync block) and iterating it for reading, or using a
ReadWrite
lock. They all depend on your exact requirement.It looks that there is another thread using the same collection and modifing it when this code is iterating over the collection.
ConcurrentModificationException
You can use navite java concurrent collestions instead. They are thread safe. However it's a good habbit to create immutable collections - they are thread safe and enforce you to design reliable code.