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 ?
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 ?
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.
Iterator
est créé, la valeur actuelle du compteur est incorporée dans le fichier Iterator
objet.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. ."
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.
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.
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 :
Fail-Safe :
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.