Проблема исправления ConcurrentModificationException

1

У меня проблема. При обращении к Vector одновременно я получаю исключение ConcurrentModificationException. Я добавил синхронизированные блоки ко всем векторным итерациям, но, возможно, забыл один или есть еще одна утечка.

Проблема заключается в том, что в ошибке stacktrace показанная ошибка - это вызов Vector.retainAll(), который является синхронизированным методом. Как я могу догадаться, в чем заключается другая причина столкновения?

заранее спасибо

 08-24 13:37:25.968: ERROR/AndroidRuntime(6582): java.util.ConcurrentModificationException
 08-24 13:37:25.968: ERROR/AndroidRuntime(6582):     at java.util.AbstractList$SubAbstractList.listIterator(AbstractList.java:320)
 08-24 13:37:25.968: ERROR/AndroidRuntime(6582):     at java.util.AbstractList$SubAbstractList.iterator(AbstractList.java:307)
 08-24 13:37:25.968: ERROR/AndroidRuntime(6582):     at java.util.AbstractCollection.contains(AbstractCollection.java:128)
 08-24 13:37:25.968: ERROR/AndroidRuntime(6582):     at java.util.Collections$SynchronizedCollection.contains(Collections.java:432)
 08-24 13:37:25.968: ERROR/AndroidRuntime(6582):     at java.util.AbstractCollection.retainAll(AbstractCollection.java:319)
 08-24 13:37:25.968: ERROR/AndroidRuntime(6582):     at java.util.Vector.retainAll(Vector.java:856)
  • 0
    Collection # SynchronizedCollection не будет блокировать сохраненную коллекцию во время итерации. читать документацию
  • 0
    Покажите некоторый код!
Теги:
multithreading
thread-safety

2 ответа

4
Лучший ответ

Проверьте код, в котором вы структурно изменяете Vector (добавление или удаление) при его повторении - это, скорее всего, причина, по которой вы получаете CME. Используйте итератор, чтобы сделать такую модификацию, чтобы избежать CME

void unsafeMod(Vector data) {
    for (Object o : data) {
        if (o != null) {
            data.remove(o); // may cause CME
        }
    }
}

Также я советую использовать ArrayList вместо Vector.

  • 1
    На самом деле, это единственный способ получить CME. Тот факт, что может быть задействовано несколько потоков, не меняет этого. Подобный, но не точный дубликат этого одного stackoverflow.com/questions/602636/…
1

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

Возвращает и передает копии вектора из методов объекта-холста или возвращает/передает немодифицируемую версию (используя Collections.unmodifiableList()). retainAll, retainAll немодифицируемого списка приведет к нарушению кода, выполняющего вызов retainAll.

Сторона примечания: Vector устарел и больше не должен использоваться. Как вы только что заметили, тот факт, что он синхронизирован, не защищает вас от одновременных ошибок доступа. Поэтому лучше использовать ArrayList.

  • 0
    Может ли Даунвотер объяснить свое понижение?
  • 0
    Мои извинения, я изначально понизил голосование, потому что CME не является проблемой, связанной с многопоточностью, и я собирался прокомментировать это. После более тщательного изучения вопроса и понимания ошибки, возникшей в методе retainAll (), я понял, что в этом случае это проблема с многопоточностью, к сожалению, я не могу изменить свой голос, поскольку прошло слишком много времени.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню