I am getting the a ConcurrentModificationException from my cooldown timer. I use a thread to reduce the values every second like this:
public class CoolDownT
Unlike Array
, Collections
are Checked only during the Compilation time, NOT during the run time, thats the reason you cannot modify the Collection like put() or remove() in the loop.
You can't modify collections when using a foreach loop.
You can however iterate over the Map.entrySet()
and do everything you need:
public void run() {
for (Iterator<Map.Entry<String,Integer>> i = playerCooldowns.entrySet().iterator(); i.hasNext();) {
Map.Entry<String,Integer> entry = i.next();
entry.setValue(entry.getValue() - 20); // update via the Map.Entry
if (entry.getValue() <= 0) {
i.remove(); // remove via the iterator
}
}
}
A ConcurrentModificationException
is thrown while you try to modify the contents of your Collection
, at the same time while Iterating
through it.
Read this and this for more discussion on it.
The reason why sometimes it might work out for you is clearly mentioned in the documentation.
The iterators returned by all of this class's "collection view methods" are fail-fast: if
the map is structurally modified at any time after the iterator is created, in any way
except through the iterator's own remove method, the iterator will throw a
ConcurrentModificationException. Thus, in the face of concurrent modification, the
iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic
behavior at an undetermined time in the future.
Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally
speaking, impossible to make any hard guarantees in the presence of unsynchronized
concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a
best-effort basis.