2012-10-20 67 views
1

我遇到了一個我無法弄清楚的問題。 會超,如果你們可以幫助我=)Iterator,ListIterator和List

我有了一個平局()方法Lobby.Class:

public void draw() { 
    //USE ITERATOR TO DRAW 
    Iterator<Player> itr = players.iterator(); 
    while(itr.hasNext()) { 
     Player player = itr.next(); 
     int off = players.indexOf(player); //THE CORRECT HEIGHT 
     player.draw(off); 
    } 
} 

請注意,這是一個服務器/客戶端遊戲

該Lobby.Class也具有)1種方法稱爲addPlayer(

public void addPlayer(String _playerName, String _class, String _string_id) { 

    int _id = Integer.parseInt(_string_id); 

    //CREATE THE NEW PLAYER 
    Player new_player = new Player(x, y, _id, _playerName, _class); 

    //IF THIS PLAYER IS ME 
    if(new_player.getID() == id) { 

     me = new_player; 

    } else { 

     //TELL THE NEW PLAYER I EXIST 
     ClientValue.getClient().iExist(_id); 

        //THIS WILL SEND TO CLIENT THAT WILL SEND TO THE SERVER 
        //THAT WILL LOOK FOR THE ID AND SEND TO CLIENT OF THAT ID 
        //AND THE CLIENT WILL SEND TO LOBBY UPDATE PLAYERS() 
    } 

    players.add(new_player); 

    chat.appendChat(chat.joinString(_playerName, _class)); 
} 

的Lobby.Class也具有1個的方法稱爲updatePlayers()

public void updatePlayers(String _playerName, String _class, String _string_id) { 

    //THIS IS CALLED WHEN THE SERVER TELLS THIS PLAYER 
    //ABOUT OTHER PLAYERS 

    int _id = Integer.parseInt(_string_id); 

    //CREATE THE NEW PLAYER 
    Player new_player = new Player(x, y, _id, _playerName, _class); 
    players.add(new_player); 

} 

現在我的問題是球員列表中,當我進入大廳addPlayer()將在何時2個玩家加入,或者當updatePlayers()addPlayer()

運行的例外,我得到的是同一時間運行:ConcurrentModificationException的

我缺少兩種方法,1 增加玩家與一個Iterator如果可能的話,1 去除PLA你好。所以我不會在修改播放列表的時候遇到錯誤或者添加/刪除它。

我已經試過用Iteror和ListIterator困惑,但由於我從來沒有用過它們,我不知道該怎麼做。我需要一些關於如何做到這一點的建議。 提前感謝=)

解決方案:

private List<Player> players = Collections.synchronizedList(new ArrayList<Player>()); 

    public synchronized void playersList(String cmd, Player _player) { 

    Iterator<Player> itr = players.iterator(); 

    if(cmd.equals("draw")) { 

     while(itr.hasNext()) { 

      Player player = itr.next(); 
      int off = players.indexOf(player); 
      player.draw(off); 
     } 

    } else if(cmd.equals("add")) { 

     players.add(_player); 

    } else if(cmd.equals("remove")) { 

     players.remove(_player); 
    } 
} 
+3

「*此類的iterator和listIterator方法返回的迭代器是快速失敗的:如果清單在任何時候都會在結構上進行修改除了通過迭代器自己的刪除或添加方法以外,任何方式都會創建e迭代器,迭代器將引發ConcurrentModificationException。*「。你無法避免它,[見](http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html)。 – Lion

+0

好吧,但是如果我在我的類的頂部初始化一個Iterator,然後使用該迭代器添加和刪除,那會怎樣。另外我注意到Iterator沒有添加方法,這是否意味着我必須使用ListIterator? –

+0

你看到了你的鏈接,我會看看我是否找到解決方案。 –

回答

1

您需要同步訪問列表,只允許一個線程同時訪問列表。

你可以使用圍繞每個接入點的​​塊(包括整個paint方法),或者您可以使用Collections#synchronizedList包裹球員名單的線程安全列表或代替迭代器,你可以使用的球員toArray方法

Player[] arrayOfPlayers = players.toArray(new Player[players.size()]); 

你仍然要​​了這個電話,但你只能鎖定一個行,而不是整個循環

+0

好的,非常感謝。但與Lobby.Class交談的唯一線索是Client.Class。所以只有一個線程,我是否仍然需要同步或使用線程安全列表?所有問題都可以。 –

+1

嗯,實際上,它看起來像兩個線程正在訪問您的列表,否則你不會有一個併發修改異常。迭代它時,不能更改列表。您需要同步acces,以便更新或迭代它,而不是同時使用 – MadProgrammer

+0

爲什麼在這種情況下不使用CopyOnWriteArrayList? – Mik378

相關問題