Использование синхронизированных списков - PullRequest
0 голосов
/ 07 августа 2010

Я впервые использую ключевое слово synchronized, поэтому я до сих пор не уверен, как оно работает. У меня есть список, к которому я хочу получить доступ из нескольких потоков, поэтому я делаю это:

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

Теперь я хочу убедиться, что я не вызываю players.add() одновременно с players.get(), поэтому я думаю, что я должен использовать синхронизированные операторы (методы A и B могут быть вызваны одновременно): 1007 *

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

Это правильная процедура? Если нет, то что мне делать вместо этого?

1 Ответ

2 голосов
/ 07 августа 2010

При условии, что вы получаете доступ к списку только через объект, возвращенный synchronizedList, тогда доступ должен быть поточно-ориентированным, хотя учтите, что вам может понадобиться использовать синхронизированные блоки для составных действий, таких как перебор списка или принятие действий и решений на основе нескольких вызовов. в список (например, получение значения, принятие решения и добавление значения).

Так что в вашем примере A () не нужен синхронизированный блок, но B () может понадобиться, если вы не хотите, чтобы список был изменен или прочитан каким-либо другим потоком во время итерации. (На самом деле, при использовании счетчика для его итерации - это , что необходимо для предотвращения условия гонки между условием завершения цикла и другим потоком, удаляющим элемент; хотя другие способы итерации могут не иметь этой проблемы).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...