我从我的冷却时间得到一个ConcurrentModificationException的。 我使用一个线程来降低每一秒这样的值:
public class CoolDownTimer implements Runnable {
@Override
public void run() {
for (String s : playerCooldowns.keySet()) {
playerCooldowns.put(s, playerCooldowns.get(s) - 20);
if (playerCooldowns.get(s) <= 0) {
playerCooldowns.remove(s);
}
}
}
}
所以每一秒钟就应减少每个球员20冷却时间,但问题是,我一个获得CME每几个小时运行程序时,尤其是当很多人在线。 如何让这个如果它仍是修改列表,它会等待,直到当前操作完成,并创造一种修改队列? 谢谢! 这里是堆栈跟踪:
2012-06-18 20:59:05 [WARNING] Task of 'SurvivorsClasses' generated an exception
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:839)
at java.util.HashMap$KeyIterator.next(HashMap.java:874)
at me.zachoooo.survivorclasses.CoolDownManager$CoolDownTimer.run(CoolDownManager.java:13)
at org.bukkit.craftbukkit.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:126)
at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:533)
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:459)
第13行是for循环的开始......
使用foreach循环时,您不能修改的集合。
但是,您可以遍历Map.entrySet()
做你需要的一切:
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
}
}
}
一个ConcurrentModificationException
,而你试图修改的内容被抛出Collection
,同时,在同一时间Iterating
通过它。
阅读这和这有关它的更多讨论。
为什么有时它可能会制定出适合您的原因中明确提到的文档 。
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.
Unlike Array
, Collections
只在编译时 检查 ,而不是在运行时间 ,这就是在循环中,您不能修改该集合就像放(),或删除的原因()。