2014-10-01 1 views
0

현재 Java로 멀티 플레이어 게임을 프로그래밍 중입니다. 내 현재 코드 (즉, 오류가 점점)입니다.ConcurrentModificationException, 수정이 없음

@Override 
public void onClose(WebSocket conn, int code, String reason, boolean remote){ 
    System.out.println("Socket disconnected."); 

    for(Game g : Lobby.games){ 
     if(g.hasPlayer(new Player(conn))){ 
      Player ourPlayer = null; 

      for(Player p : g.getPlayers()){ 
       if(p.getSocket() == conn){ 
        ourPlayer = p; 
        break; 
       } 
      } 

      if(ourPlayer == null) return; 

      g.removePlayer(ourPlayer); 

      for(Player p : g.getPlayers()){ 
       send(p.getSocket(), Messages.SEND_REMOVE_PLAYER + ourPlayer.getName()); 
      } 

      if(g.getPlayers().size() == 0){ 
       Lobby.removeGame(g); 
      } 
     } 
    } 
} 

이제 onClose와 같은 기능에 대해 묻지 마십시오. 그것은 문제를 일으키지 않습니다.

나는 다음 줄 ConcurrentModificationException를 얻고있다 :

for(Game g : Lobby.games){ 

Lobby.games는 Lobby.java 내부 "게임"의 빈 ArrayList를합니다. 게임은 다른 기능을 통해 추가됩니다.

public static ArrayList<Game> games = new ArrayList<Game>(); 

업데이트 : 모호한 것에 대한

public static void removeGame(Game game){ 
    Iterator<Game> itr = games.iterator(); 

    while(itr.hasNext()){ 
     Game g = itr.next(); 

     if(g.getId() == game.getId()){ 
      System.out.println("Game "+g.getId()+" removed"); 
      itr.remove(); 
     } 
    } 
} 

죄송합니다 : 그리고 이것은 removeGame입니다. 더 많은 코드가 필요하다면 반드시 추가 할 것입니다. 감사!

+0

반복자를 사용하는 경우에만 개체를 ​​변경할 수 있습니다. –

+0

첫째, 이미 반복기를 사용해 보았습니다. 둘째, 반복자를 사용하는 함수가없는 것은 수정하지 않습니다. – anonmous

+1

'Lobby.removeGame (g);'은 루프에서'Lobby.games'를 조작하고 있음을 나타냅니다. – njzk2

답변

0

Lobby.removeGame(g) 호출은 암시 적 순서를 완전히 무효화하는 지금 반복하고 있다는 사실에도 불구하고 목록을 수정하려는 것입니다.

이 작업을 수행해야하는 경우는 아직에 당신이 못 했어 부품의 순서에 영향을 미치지 않을 목록의 일부를 수정하고 있도록 명시 적으로 반대 루프를 사용

for(int i=Lobby.games.size()-1; i>-1; i--) { 
    Game g = Lobby.games.get(i); 

    // this is now safe, because you're only ever going to see 
    // indices lower than the current "i", and the removal 
    // only how long Lobby.games is *after* "i", not before it. 
    Lobby.games.remove(g) 
} 
+0

대단히 감사합니다! – anonmous

2

의 문제가이 (거의 확실)입니다 : Lobby.removeGame(g)Lobby.games의 내용을 변경

for(Game g : Lobby.games) { 
    // other code 
    if (g.getPlayers().size() == 0){ 
     Lobby.removeGame(g); 
    } 
} 

경우 (Lobby.games을 통해 암시 적으로 반복을 foreach 루프)의 반복하는 동안, 당신은 Lobby.games 수정됩니다.

반복자를 사용하고 Iterator.remove()으로 전화하거나 루프 이후에 제거 할 게임 컬렉션을 저장하거나 그렇지 않으면 코드를 재구성하여 이러한 상황을 피하십시오.

관련 문제