Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > java.util.ConcurrentModificationException


Автор: light0ff 6.2.2006, 13:25
У меня есть форма. При ее закрытии мне необходимо сохранять параметры формы в файл. Делаю это примерно вот так.

Код

    public static void setAbstractForm(AbstractForm form) {
        FormConfigObject configObject = new FormConfigObject(form.getClass().getName(), form.getLocation(),   form.getSize());
        Collection formConfigObjects = getAllFormConfigObjects();

        if (isObjectExist(configObject)) {
            for (Iterator it = formConfigObjects.iterator(); it.hasNext();) {
                FormConfigObject obj = (FormConfigObject) it.next();
                if (obj.getFormId().equals(configObject.getFormId()))
                    formConfigObjects.remove(obj);
            }
        }
        formConfigObjects.add(configObject);
        writeConfigToFile(formConfigObjects);
    }


При первом создании, когда объект еще не существует, все нормально.
При повторном сохранении вылетает исключение (java.util.ConcurrentModificationException) в строчке "FormConfigObject obj = (FormConfigObject) it.next();". В чем может быть проблема?

Автор: Beard 6.2.2006, 13:31
У вас два потока имеют одновременный доступ к коллекции, причем другой (первый - где вы итерируете), по всей вероятности
пытается удалить элеммент.
Как написано в документации:
This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.

For example, it is not generally permissible for one thread to modify a Collection while another thread is iterating over it.

Synchronize поможет

Автор: aefimov 6.2.2006, 17:37
Дело в том, что вы итерируетесь по списку. И в этот момент пытаетесь удались из него что-то, но не средствами итератора, а через саму коллекцию. Пользуйтесь методом delete у java.util.Iterator для корректного удаления во время итерирования.
Добавлено @ 17:38
сорри, метод remove, конечно же. smile

Автор: light0ff 6.2.2006, 21:45
Огромное спасибо;)

Автор: Platon 16.5.2007, 14:19
Beard, 
Простите что подымаю снова тему, но у меня не идут synch-и никак.

Код

protected void notifyAuth(Message message) throws IOException {
        synchronized(authListeners) {
            for (Listener listener : authListeners)
                listener.fireMessage(message);
        }
    }

public void removeAuthListener(ClientAuthListener listener) {
        synchronized(authListeners) {
            authListeners.remove(listener);
        }
    }


что же тут не так?
Точнее я знаю что тут не так, ситуация такая: сначала вызывается notifyAuth, первый слушатель обрабатывает сообщение и убивает 2-го слушателя посредством removeAuthListener,
все логично было бы если бы я убрал synchronized блоки, но когда они есть, почему все равно проскакивает конкурент?

Автор: tipoc 18.5.2007, 00:10
Хех, синхронизация не поможет. 
Написано ведь черным по белому:
Цитата

it is not generally permissible for one thread to modify a Collection while another thread is iterating over it

Методы итератора (если он fail-fast) все равно обнаружат, что ты модифицировал коллекцию в другом потоке вне зависимости от того, сделал ли ты это синхронизировано или нет.

Автор: Бонифаций 18.5.2007, 00:50
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/CopyOnWriteArrayList.html

Автор: Platon 18.5.2007, 10:22
Угу, жестоко поступаю smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)