0

キーワードを使用するのはこれが初めてsynchronizedなので、正確にどのように機能するかはまだわかりません。複数のスレッドからアクセスしたいリストがあるので、次のようにします。

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

players.add()ここで、 と同時に呼び出していないことを確認したいplayers.get()ので、同期ステートメントを使用する必要があると思います (メソッド A と B は同時に呼び出すことができます)。

public void A() {
    synchronized(players) {
        players.add(new Player());
    }
}

public void B(String msg) {
    synchronized(players) {
        for(int i = 0;i<players.size();i++) {
            players.get(i).out.println(msg);
        }
    }
}

これは正しい手順ですか?そうでない場合、代わりに何をすべきですか?

4

1 に答える 1

2

synchronizedList によって返されたオブジェクトを介してのみリストにアクセスする場合、アクセスはスレッドセーフである必要がありますが、リストを反復処理したり、リストへの複数の呼び出しに基づいてアクションや決定を行ったりするなどの複合アクションには、同期ブロックを使用する必要がある場合があることに注意してください。 (たとえば、値を取得して決定を下し、値を追加します)。

したがって、あなたの例では A() は同期ブロックを必要としませんが、反復中にリストを変更したり、他のスレッドで読み取ったりしたくない場合は B() が必要になる場合があります。(実際、カウンターを使用して反復することにより、ループ終了条件とアイテムを削除する別のスレッドとの間の競合状態を防ぐ必要があります。ただし、他の反復方法ではこの問題は発生しない可能性があります)。

于 2010-08-07T18:20:00.960 に答える