2013-04-13 27 views
0

我正在開發通過網絡播放的多人蛇遊戲。 它運行良好,但它偶爾會拋出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(); 
    } 
} 
+0

)將優化你的代碼。 – Aubin

+0

「地圖」在哪裏更改(「放」或「移除」)? – acdcjunior

+0

這是在線程的啓動,我會發布上面的代碼。 儘管在這種情況下,該部分並沒有採用併發性,因爲paintComponent僅在啓動完成後才運行 – Sohaib

回答

1

更改地圖的實現類,以一個支持的併發如使用的entrySet()代替鍵集(ConcurrentHashMap

+2

可能會解決這個問題,但我必須指出它是不能保證的:[請注意,'ConcurrentModificationException'並不總是表明一個對象已被_different_線程同時修改。](http://docs.oracle.com/ JavaSE的/ 1.5.0 /文檔/ API/JAVA/util的/ ConcurrentModificationException.html) – acdcjunior