我正在開發通過網絡播放的多人蛇遊戲。 它運行良好,但它偶爾會拋出java.util.ConcurrentModification異常。 這是在paintComponent()方法中我的遊戲的主類中拋出的。在此拋出代碼在兩個線程中使用相同的Hashmap時,Hashmap中的併發修改異常
for (String name : map.keySet()) {
if (!map.get(name).gameover) {
for (int i = 0; i < map.get(name).length; i++) {
rect = new Rectangle2D.Double(map.get(name).p[i].x,
map.get(name).p[i].y, width, width);
g1.setColor(Color.black);
g1.draw(rect);
g1.setPaint(map.get(name).snakecolor);
g1.fill(rect);
}
}
}
HashMap的地圖是從
HashMap<String,Snake>
一個映射,其中蛇是有蛇的所有屬性的類。 主類還並行運行線程,通過服務器從其他客戶端接收消息和更新。
線程端的迭代器也使用相同的映射(通過引用傳遞給該類)。代碼如下。如果任何玩家的得分達到升級後的某個特定點,則調用此函數。
void levelUp(int level){
for(String name:map.keySet()){
map.get(name).level=level;
}
Game.speed=100/level;
}
我認爲寫對象之間的衝突是由於這一點。任何人都可以請建議這個問題的解決方案。
下面給出了將值放入地圖的代碼。
void populateMap() {
try {
try {
objin = new ObjectInputStream(socket.getInputStream());
} catch (StreamCorruptedException e) {
System.out.println("Stream Corrupted!");
}
Object name = objin.readObject();
if (((Snake) name).player.equals("food_coord")) {
Game.foodx = objin.readInt();
Game.foody = objin.readInt() + 35;
start = true;
System.out.println("Game Started");
return;
} else {
map.put(((Snake) name).player, (Snake) name);
System.out.println("Recieved: " + ((Snake) name).player);
}
} catch (java.net.SocketException s) {
JOptionPane.showMessageDialog(null, "Server Closed", "ERROR",
JOptionPane.ERROR_MESSAGE);
System.exit(0);
} catch (Exception e) {
e.printStackTrace();
}
}
)將優化你的代碼。 – Aubin
「地圖」在哪裏更改(「放」或「移除」)? – acdcjunior
這是在線程的啓動,我會發布上面的代碼。 儘管在這種情況下,該部分並沒有採用併發性,因爲paintComponent僅在啓動完成後才運行 – Sohaib