#java #design-patterns #observer-pattern
#java #шаблоны проектирования #observer-pattern
Вопрос:
Предположим, что у вас реализован шаблон наблюдателя и что наблюдатели могут решить отменить регистрацию себя (или других наблюдателей) из вашего объекта в методе onUpdate.
Предполагая, что вы используете ArrayLists для сохранения ваших наблюдателей, это приведет к java.util.Исключение ConcurrentModificationException, поскольку вы удаляете элементы во время итерации по списку.
Какой самый лучший способ решить эту проблему?
В настоящее время я клонирую список, чтобы выполнить итерацию по клону для метода onUpdate, но я считаю, что должны быть лучшие решения…
Ответ №1:
Существует ряд коллекций, которые поддерживают это. Например, jME3 использует свой собственный вариант ArrayList called SafeArrayList
. Это проект с открытым исходным кодом, поэтому вы можете найти реализацию там.
Лучшим решением, чем клонирование при каждом чтении, является копирование списка при изменении. Просто создайте новый список, внесите в него изменения, назначьте его обратно в свой список слушателей.
В большинстве случаев изменения в наблюдателях происходят реже, чем цикл над наблюдателями.
Если вы скопируете список и измените клон, то все, что повторяется по предыдущей версии списка, не увидит изменения, но также не будет исключением.
Ответ №2:
Повторение копии, как вы это делаете в данный момент, является одним из решений. Использование a CopyOnWriteArrayList
было бы еще одним потокобезопасным. Конечно, оба имеют определенные накладные расходы.