gpt4 book ai didi

java - 迭代器、列表迭代器和列表

转载 作者:太空宇宙 更新时间:2023-11-04 08:00:00 25 4
gpt4 key购买 nike

我遇到了一个我不太明白的问题。如果你们能帮助我那就太好了 =)

我有一个 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 还有 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 用于使用迭代器添加玩家(如果可能),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);
}
}

最佳答案

您需要同步对列表的访问,一次只允许一个线程访问该列表。

您可以在每个访问点(包括整个绘制方法)周围使用synchronized block ,或者您可以使用 Collections#synchronizedList 将播放器列表包装在线程安全列表中或者,您可以使用players的toArray方法来代替迭代器

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

您仍然要同步 this 调用,但您只锁定一行,而不是整个循环

关于java - 迭代器、列表迭代器和列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12992051/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com