Этот вопрос является более частным случаем проблемы, описанной (и решенной) в этом вопросе.
У меня есть два метода: stopAndRemove (ServerObject server) и метод close(). Позднее следует закрыть все серверы и удалить их из списка серверов. Список определяется как
List<ServerObject> server.
Я не хочу иметь почти тот же код из stopAndRemove в closeCurrentlyOpen, поэтому я хочу сделать что-то вроде:
public void closeCurrentlyOpen() {
for(ServerObject server : this.servers) {
stopAndRemove(server)
}
}
Это не сработает, так как это вызовет исключение ConcurrentModificationException. Я попытался сделать копию списка
List<ServerObject> copyList = new ArrayList<ServerObject>(this.servers);
и использовать это как список для цикла foreach. Но тогда возможно, что другой поток присоединяет сервер к списку серверов, пока я выполняю повторение с помощью copyList, но closeCurrentlyOpen должен приводить к списку emtpy. Поскольку метод addServerToList синхронизируется с списком серверов, выполните
public void closeCurrentlyOpen() {
synchronized(this.servers) {
for(ServerObject server : this.servers) {
stopAndRemove(server)
}
}
}
решит проблему с модификациями. Но тогда я не могу синхронизировать код в методе stopAndRemove, который необходим, если он вызван напрямую.
Мне кажется, что дизайн этих трех методов, вероятно, нуждается в капитальном ремонте. Идеи кто-нибудь?