web-dev-qa-db-fra.com

Que sont les itérateurs de sécurité et de sécurité dans Java

Il existe deux types d'itérateurs en Java: le type sécurisé et le système rapide.

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

95
Prateek

Quelle est la différence entre eux ...

"Fail safe" signifie: cela n'échouera pas. Strictement parlant, il n'y a rien de tel dans Java en tant qu'itérateur à sécurité intrinsèque. Le terme correct est "faiblement" cohérent ". Le javadoc dit:

"La plupart des implémentations de Collection simultanées (y compris la plupart des files d'attente) diffèrent également des conventions Java.util habituelles en ce que leurs itérateurs et spliterateurs fournissent une traversée faiblement cohérente plutôt que rapide."

En règle générale, une cohérence faible signifie que si une collection est modifiée en même temps qu'une itération, les garanties de ce que voit l'itération sont plus faibles. (Les détails seront spécifiés dans chaque collection javadocs des classes de collection simultanées.)

"Echec rapide" signifie: it peut échouer ... et la condition d'échec est vérifiée de manière agressive afin que la condition d'échec soit (si possible).1) détecté avant dommages peuvent être causés. En Java, un itérateur fail-fast échoue en lançant un ConcurrentModificationException.

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

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

Ce sont des propriétés des itérateurs implémentés par les types de collection standard; c'est-à-dire qu'ils sont soit "échec rapide", soit "faiblement cohérent" ... lorsqu'ils sont utilisés correctement en ce qui concerne la synchronisation et le modèle de mémoire Java1.


Les itérateurs de type fast-fast sont généralement implémentés à l'aide d'un compteur volatile sur l'objet de 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 l'objet Iterator.
  • Lorsqu'une opération Iterator est effectuée, la méthode compare les deux valeurs de compteur et envoie une CME si elles sont différentes.

L'implémentation d'itérateurs à sécurité intrinsèque est généralement légère. Ils s'appuient généralement sur les propriétés des structures de données de l'implémentation de liste spécifique. Il n'y a pas de tendance générale. (Lisez le code source des classes de collection spécifiques qui vous intéressent.)


1 - Le coureur considère que le comportement anti-panne suppose que l'id de l'application est correct par rapport à la synchronisation et au modèle de mémoire. Cela signifie que (par exemple) si vous répétez une ArrayList sans synchronisation appropriée, le résultat pourrait être un résultat de liste corrompu. Le mécanisme "d'échec rapide" détectera probablement la modification simultanée (bien que cela ne soit pas garanti), mais il ne détectera pas la corruption sous-jacente. Par exemple, javadoc pour Vector.iterator() dit ceci:

"Le comportement d'un itérateur à la suite d'une panne rapide ne peut pas être garanti car il est généralement impossible de donner des garanties fermes en présence de modifications simultanées non synchronisées. Les itérateurs à la suite d'une panne rapide lancent ConcurrentModificationException au mieux. Par conséquent, il serait erroné d’écrire un programme dont l’exactitude dépend de cette exception: le comportement à la suite d’une défaillance rapide des itérateurs ne devrait être utilisé que pour détecter des bogues. "

80
Stephen C

Ce sont plutôt les types fail-fast et faiblement cohérent:

Itérateurs de Java.util package jette ConcurrentModificationException si la collection a été modifiée par les méthodes de la collection (ajout/suppression) lors de l'itération

Itérateurs de Java.util.concurrent package généralement itérer sur un instantané et permettre des modifications simultanées, mais peut ne pas refléter les mises à jour de la collection après la création de l'itérateur.

40
Evgeniy Dorofeev

La seule différence est que l'itérateur à sécurité intrinsèque ne lance aucune exception, contrairement à Itérateur à sécurité rapide.

Si Collection est modifié structurellement pendant qu'un thread l'itère. C’est parce qu’ils travaillent sur un clone de Collection au lieu de la collection originale et c’est pourquoi ils sont appelés itérateurs de sécurité.

Iterator de CopyOnWriteArrayList est un exemple d'Iterator de sécurité Iterator également un itérateur écrit par ConcurrentHashMap keySet est également un itérateur de sécurité et ne lève jamais ConcurrentModificationException en Java.

22
Juned Ahsan