Iterator Modification concurrente Exception
-
20-09-2019 - |
Question
Ce code lancera une modification concurrente Exception si la liste est modifiée doSomething (). Est-il possible de l'éviter en plaçant le code dans un bloc synchronisé?
List l = Collections.synchronizedList(new ArrayList());
// normal iteration -- can throw ConcurrentModificationException
// may require external synchronization
for (Iterator i=list.iterator(); i.hasNext(); ) {
doSomething(i.next());
}
La solution
-
si vous supprimez un élément de la liste, vous pouvez le faire en appelant
iterator.remove()
au lieu delist.remove(iterator.next())
-
si vous ajoutez un élément - bien, créer une copie de la liste et l'ajouter itéré y
-
si l'extrait de code ci-dessus est une partie de la même méthode, vous n'avez pas besoin d'une liste synchronisée ou blocs synchronisés -. Aucun autre thread peut accéder à la liste locale
Autres conseils
peut modifier un Iterator
interface . Vous pouvez utiliser Iterator.remove()
pour supprimer des éléments.
Vous ne pouvez pas modifier pendant que vous itérez dessus. Ne va pas aider Synchroniser ici.
EDIT: J'oublié iterator ne possède la méthode remove
. Il est donc possible de supprimer.
Je suis d'accord avec les autres sur Iterator
et remove()
.
A propos de la synchronisation, je voulais ajouter que la synchronisation est conçu pour contrôler les interactions entre les différents threads .
Il est typique pour un objet d'avoir plusieurs méthodes synchronisées, et que l'on appellerait un autre. Ainsi, les concepteurs de langage ont décidé que le même fil ne serait pas bloqué par lui-même sur une synchronisation.
En outre, d'y penser, un fil est bloqué en attente pour lui-même, vous avez un magnifique famine perspective! ; -)
Alors que cela répond à une de vos questions. Il est impossible d'éviter le problème en synchronisant votre code
Utilisez CopyOnWriteArrayList
au lieu de la liste Array synchronisé
List l = Collections.synchronizedList(new ArrayList());
synchronized(l) {
// normal iteration -- can throw ConcurrentModificationException
// may require external synchronization
for (Iterator i=list.iterator(); i.hasNext(); ) {
doSomething(i.next());
}
}