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());
}
Était-ce utile?

La solution

  • si vous supprimez un élément de la liste, vous pouvez le faire en appelant iterator.remove() au lieu de list.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());
   }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top