我爲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