Избегание одновременного изменения в шаблоне наблюдателя

#java #design-patterns #observer-pattern

#java #шаблоны проектирования #observer-pattern

Вопрос:

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

Предполагая, что вы используете ArrayLists для сохранения ваших наблюдателей, это приведет к java.util.Исключение ConcurrentModificationException, поскольку вы удаляете элементы во время итерации по списку.

Какой самый лучший способ решить эту проблему?

В настоящее время я клонирую список, чтобы выполнить итерацию по клону для метода onUpdate, но я считаю, что должны быть лучшие решения…

Ответ №1:

Существует ряд коллекций, которые поддерживают это. Например, jME3 использует свой собственный вариант ArrayList called SafeArrayList . Это проект с открытым исходным кодом, поэтому вы можете найти реализацию там.

Лучшим решением, чем клонирование при каждом чтении, является копирование списка при изменении. Просто создайте новый список, внесите в него изменения, назначьте его обратно в свой список слушателей.

В большинстве случаев изменения в наблюдателях происходят реже, чем цикл над наблюдателями.

Если вы скопируете список и измените клон, то все, что повторяется по предыдущей версии списка, не увидит изменения, но также не будет исключением.

Ответ №2:

Повторение копии, как вы это делаете в данный момент, является одним из решений. Использование a CopyOnWriteArrayList было бы еще одним потокобезопасным. Конечно, оба имеют определенные накладные расходы.