106 votes

Que sont les itérateurs fail-safe et fail-fast en Java ?

Il existe deux types d'itérateurs en Java : fail-safe et fail-fast.

Qu'est-ce que cela signifie, et quelle est la différence entre les deux ?

88voto

Stephen C Points 255558

Quelle est la différence entre eux ...

"Fail-safe" ( en ingénierie ) signifie que quelque chose échoue d'une manière qui ne cause aucun dommage ou des dommages minimes. À proprement parler, il y a rien de tel en Java comme un itérateur à sécurité intégrée. Si un itérateur échoue (dans le sens normal du terme "échec"), vous pouvez vous attendre à ce que des dommages se produisent.

Je soupçonne que vous voulez en fait parler d'itérateurs "faiblement cohérents". La javadoc dit :

"La plupart des implémentations de collections concurrentes (y compris la plupart des files d'attente) diffèrent également des conventions habituelles de java.util en ce que leurs Iterators et Spliterators fournissent une traversée faiblement cohérente plutôt que rapide."

Typiquement, la cohérence faible signifie que si une collection est modifiée en même temps qu'une itération, les garanties de ce que l'itération voit sont plus faibles. (Les détails seront précisés dans les javadocs de chaque classe de collection concurrente).

"Fail-fast" ( dans la conception de systèmes ) signifie que la condition de défaillance est vérifiée de manière agressive afin que la condition de défaillance soit (dans la mesure du possible) 1 ) détecté avant que les dommages ne soient trop importants. En Java, un itérateur fail-fast échoue en lançant une requête ConcurrentModificationException .

L'alternative à "fail-fast" et "weakly consistent" est sémantique où l'itération échoue de manière imprévisible ; par exemple, pour donner parfois la mauvaise réponse ou jeter une exception inattendue. (C'était le comportement de certaines implémentations standard de l'outil Enumeration dans les premières versions de Java).

... et sont-elles différentes de l'itérateur que nous utilisons pour la collecte.

Non. Ce sont propriétés des itérateurs implémentés par les types de collections standard ; c'est-à-dire qu'ils sont soit "fail fast", soit "weakly consistent" ... lorsqu'ils sont utilisés correctement en ce qui concerne la synchronisation et le modèle de mémoire Java. 1 .


Les itérateurs "fail-fast" sont généralement mis en œuvre à l'aide d'un volatile sur l'objet de la collection.

  • Lorsque la collection est mise à jour, le compteur est incrémenté.
  • Lorsqu'un Iterator est créé, la valeur actuelle du compteur est incorporée dans le fichier Iterator objet.
  • Lorsqu'un Iterator est effectuée, la méthode compare les deux valeurs du compteur et lance un CME si elles sont différentes.

En revanche, les itérateurs faiblement cohérents sont généralement légers et exploitent les propriétés des structures de données internes de chaque collection concurrente. Il n'existe pas de modèle général. Si vous êtes intéressé, lisez le code source des différentes classes de collections.


1 - Le cavalier est que le comportement fail-fast des itérateurs suppose que l'application est correctement implémentée en ce qui concerne la synchronisation et le modèle de mémoire. (En d'autres termes, le application est thread-safe). Par exemple, si vous avez itéré un ArrayList Sans une synchronisation appropriée, le mécanisme de "défaillance rapide" devrait détecter la modification concurrente (bien que cela ne soit pas garanti), mais peut ne pas empêcher la liste d'être corrompue en raison du comportement dangereux de l'application. Pour illustrer, l'application javadoc pour Vector.iterator() dit ceci :

"Le comportement infaillible d'un itérateur ne peut pas être garanti, car il est généralement impossible d'apporter des garanties solides en présence de modifications concurrentes non synchronisées. Les itérateurs "fail-fast" lancent ConcurrentModificationException sur la base du meilleur effort. Par conséquent, il serait erroné d'écrire un programme dont l'exactitude dépend de cette exception : le comportement infaillible des itérateurs ne devrait être utilisé que pour détecter les bogues. ."

42voto

Evgeniy Dorofeev Points 52031

Ils sont plutôt Fail-fast y faiblement cohérent types :

Iterators de java.util lancer le paquet ConcurrentModificationException si la collection a été modifiée par les méthodes de la collection (add / remove) pendant l'itération.

Iterators de java.util.concurrent itèrent généralement sur un instantané et permettent des modifications simultanées mais peuvent ne pas refléter les mises à jour de la collection après la création de l'itérateur.

22voto

Juned Ahsan Points 33217

La seule différence est que l'itérateur fail-safe ne lève pas d'exception, contrairement à l'Iterator fail-fast.

Si la structure de la collection est modifiée alors qu'un thread est en train de la parcourir. C'est parce qu'ils travaillent sur un clone de la collection au lieu de la collection originale et c'est pourquoi ils sont appelés itérateurs à sécurité intégrée.

L'itérateur de CopyOnWriteArrayList est un exemple d'itérateur à sécurité intégrée. L'itérateur écrit par ConcurrentHashMap keySet est également un itérateur à sécurité intégrée et ne lève jamais d'exception ConcurrentModificationException en Java.

2voto

Dhwanil Patel Points 488

Ce scénario est lié au "traitement simultané", ce qui signifie que plus d'un utilisateur accède à la même ressource. Dans une telle situation, l'un des utilisateurs essaie de modifier cette ressource, ce qui provoque une 'ConcurrentProcessingException', car dans ce cas, les autres utilisateurs obtiennent des données incorrectes. Ces deux types d'exception sont liés à ce genre de situation.

En termes simples,

Fail-Fast :

  • Les itérateurs lèvent immédiatement l'exception ConcurrentModificationException si une modification structurelle (ajout, mise à jour, suppression) se produit.
  • Exemple : ArrayList, HashMap, TreeSet

Fail-Safe :

  • Ici, les itérateurs ne lèvent pas d'exception car ils opèrent sur le clone de la collection et non sur l'original. Ainsi, ce sont des itérateurs à sécurité intégrée.
  • Exemple : CopyOnWriteArrayList, ConcurrentHashMap

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X