2012-10-20 41 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

相关问题