1

まったく理解できない問題に遭遇しました。皆さんが私を助けてくれれば最高です=)

draw() メソッドを持つ 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 には addPlayer() というメソッドも 1 つあります。

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() というメソッドも 1 つあります。

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

可能であれば Iterator を使用してプレーヤーを追加する方法と、プレーヤーを削除する方法の 2 つの方法がありません。そのため、プレーヤーリストを通過したり、追加/削除したりしているときに、プレーヤーリストを変更してもエラーが発生しません。

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);
    }
}
4

1 に答える 1

1

一度に 1 つのスレッドのみがリストにアクセスできるように、リストへのアクセスを同期する必要があります。

各アクセス ポイント (ペイント メソッド全体を含む) の周りにブロックを使用するか、イテレータの代わりにsynchronizedプレーヤー リストをスレッド セーフ リストにラップするか、プレーヤーのメソッドをCollections#synchronizedList使用することができます。toArray

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

あなたはまだこの呼び出しに行きますがsynchronized、ループ全体ではなく、1行だけをロックしています

于 2012-10-20T20:11:13.770 に答える