Ich habe eine ArrayList mit zwei Accessor-Methoden und einem Notifier. Meine Liste:ArrayList Iterator werfen ConcurrentModificationException
private final List<WeakReference<LockListener>> listeners = new ArrayList<>();
Alle abonnieren Operationen verwenden:
public void subscribe(@NonNull LockListener listener) {
for (Iterator<WeakReference<LockListener>> it = listeners.iterator(); it.hasNext();) {
// has this one already subscribed?
if (listener.equals(it.next().get())) {
return;
}
}
listeners.add(new WeakReference<>(listener));
}
Alle Abmeldevorgänge verwenden diese:
public void unsubscribe(@NonNull LockListener listener) {
if (listeners.isEmpty()) {
return;
}
for (Iterator<WeakReference<LockListener>> it = listeners.iterator(); it.hasNext();) {
WeakReference<LockListener> ref = it.next();
if (ref == null || ref.get() == null || listener.equals(ref.get())) {
it.remove();
}
}
}
Und den Antragsteller:
private void notifyListeners() {
if (listeners.isEmpty()) {
return;
}
Iterator<WeakReference<LockListener>> it = listeners.iterator();
while (it.hasNext()) {
WeakReference<LockListener> ref = it.next();
if (ref == null || ref.get() == null) {
it.remove();
} else {
ref.get().onLocked();
}
}
}
Was ich Ich sehe in meiner Prüfung, dass es.next() in n otifyListeners() löst gelegentlich eine ConcurrentModificationException aus. Meine Vermutung ist, dass dies auf listeners.add() in der Teilnehmermethode zurückzuführen ist.
Ich denke, ich hatte hier ein Missverständnis des Iterators. Ich ging davon aus, dass das Iterieren über die Liste mich vor Nebenläufigkeitsproblemen schützte, die durch Add/Remove-Vorgänge verursacht wurden.
Anscheinend liege ich hier falsch. Ist der Iterator nur ein Schutz vor der ConcurrentModificationException beim Ändern der Sammlung, die Sie gerade durchlaufen? Wenn Sie z. B. während der Iteration remove() auf Ihrer Liste aufrufen, wird zwar ein Fehler ausgegeben, der Aufruf von it.remove() ist jedoch sicher.
In meinem Fall, subskribieren Anrufe() auf der gleichen Liste wie es iteriert wird. Ist mein Verständnis hier korrekt?
Wenn Sie die Dokumentation für Iterator lesen, wird Ihnen mitgeteilt, dass Sie die zugrunde liegende Struktur nicht ändern können – efekctive