Проблема исправления ConcurrentModificationException - PullRequest
1 голос
/ 24 августа 2011

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

Проблема в том, что в трассировке стека ошибок показанная ошибка является вызовом 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)

Ответы [ 2 ]

4 голосов
/ 24 августа 2011

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

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

Также я рекомендую совет , чтобы использовать ArrayList вместо Vector.

1 голос
/ 24 августа 2011

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...