我为Minecraft服务器开发插件。最近在我的测试服务器上,从ArrayList或Hashmap中删除对象时,我一直有重复的崩溃。程序在从HashMap中删除对象时挂起?
首先,它似乎是从ArrayList中删除某个东西。但是,它现在似乎能够在从任何ArrayList/HashMap中删除某些东西时随机发生。
在这种特定情况下,代码行是entlist.get(pl.getName()).remove(en);
与周围的代码是
for (LivingEntity en: remove) {
i++;
if (entlist.containsKey(pl.getName())) {
entlist.get(pl.getName()).remove(en);
}
if (i > 2000) {
try {
throw new Exception("Too many entities to remove!!");
} catch (Exception e) {
e.printStackTrace();
}
break;
}
}
entlist是HashMap<String, ArrayList<LivingEntity>> entlist = new HashMap<String, ArrayList<LivingEntity>>();
。
胎面转储特别列出了ArrayList#remove()
作为问题。
[09:53:51 ERROR]: Current Thread: Server thread
[09:53:51 ERROR]: PID: 14 | Suspended: false | Native: false | State: RUNN
ABLE
[09:53:51 ERROR]: Stack:
[09:53:51 ERROR]: java.util.ArrayList.remove(ArrayList.java:481)
[09:53:51 ERROR]: a.e$4.run(Main.java:1786) //Line 1786 being the `entlist.get(pl.getName()).remove(en);` line from earlier.
Java版本:
C:\WINDOWS\system32>java -version
java version "1.7.0_11"
Java(TM) SE Runtime Environment (build 1.7.0_11-b21)
Java HotSpot(TM) Client VM (build 23.6-b04, mixed mode, sharing)
此外,由于有人在评论中问道,I've pastebinned the entire thread dump that Spigot puts out当它检测到的冻结。
为什么简单地从ArrayList/HashMap中删除一个值来冻结整个服务器?
我花了几个小时试图让一切都同步 - 这是不可能的。我将不得不使用一个ConcurrentHashMap :(。 – Joehot200 2015-04-05 15:20:29
+1)作为第二个理论。碰撞,不太可能发生,也可能是由不好的算法造成的。 – Unihedron 2015-04-06 11:01:57
我最终在一个月后解决了这个问题,而是使用addAll()方法代替 – Joehot200 2015-05-28 12:55:21