У меня проблема. При обращении к 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)
Проверьте код, в котором вы структурно изменяете Vector (добавление или удаление) при его повторении - это, скорее всего, причина, по которой вы получаете CME. Используйте итератор, чтобы сделать такую модификацию, чтобы избежать CME
void unsafeMod(Vector data) {
for (Object o : data) {
if (o != null) {
data.remove(o); // may cause CME
}
}
}
Также я советую использовать ArrayList вместо Vector.
Просто не позволяйте кому-либо другому (чем объект, удерживающий вектор) получить доступ к вектору. Это единственный способ убедиться, что никто, кроме объекта-холдинга, не изменяет его при повторении.
Возвращает и передает копии вектора из методов объекта-холста или возвращает/передает немодифицируемую версию (используя Collections.unmodifiableList()
). retainAll
, retainAll
немодифицируемого списка приведет к нарушению кода, выполняющего вызов retainAll
.
Сторона примечания: Vector
устарел и больше не должен использоваться. Как вы только что заметили, тот факт, что он синхронизирован, не защищает вас от одновременных ошибок доступа. Поэтому лучше использовать ArrayList
.