我遇到了一个我无法弄清楚的问题。 如果你们能帮助我的话,会超级好吗=)
我有一个Lobby.Class,它有一个draw()方法:
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还有一个名为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还有一个名为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代表删除玩家。因此,我不会因为修改玩家列表或添加/删除它而得到错误。
我曾尝试使用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);
}
}
答案 0 :(得分:1)
您需要同步对列表的访问权限,一次只允许一个线程访问列表。
您可以在每个访问点周围使用synchronized
块(包括整个绘制方法),或者您可以使用Collections#synchronizedList
或者代替迭代器将播放器列表包装在线程安全列表中可以使用toArray
玩家方法
Player[] arrayOfPlayers = players.toArray(new Player[players.size()]);
你仍然要synchronized
这个电话,但你唯一锁定的一行,而不是整个循环