Frage Was sind ausfallsichere und ausfallsichere Iteratoren in Java [geschlossen]


Es gibt zwei Arten von Iteratoren in Java: fehlersicher und fehlgeschlagen.

Was bedeutet das und ist der Unterschied zwischen ihnen?


75
2018-06-29 06:27


Ursprung


Antworten:


Was ist der Unterschied zwischen ihnen ...

"Fail safe" bedeutet: Es wird nicht scheitern. Genau genommen gibt es das keine solche Sache in Java als fehlersicherer Iterator. Der richtige Begriff ist "schwach konsistent". Das Javadoc sagt:

"Die meisten parallelen Collection-Implementierungen (einschließlich der meisten Queues) unterscheiden sich auch von den üblichen java.util-Konventionen darin, dass ihre Iteratoren und Splitteratoren eher schwach konsistente als nicht schnelle Failover-Traversierungen bereitstellen."

In der Regel bedeutet schwache Konsistenz, dass, wenn eine Sammlung gleichzeitig mit einer Iteration geändert wird, die Garantien dessen, was die Iteration sieht, schwächer sind. (Die Details werden in den jeweiligen Sammlungsklassen javadocs angegeben.)

"Fail Fast" bedeutet: es kann fehlgeschlagen ... und die Fehlerbedingung wird aggressiv geprüft, so dass die Fehlerbedingung (wenn möglich) vorliegt1) entdeckt Vor Schaden kann angerichtet werden. In Java schlägt ein Fail-Fast-Iterator fehl, indem er a ConcurrentModificationException.

Die Alternative zu "fail-fast" und "schwach konsistent" ist eine Semantik, bei der die Iteration unvorhersehbar ausfällt; z.B. manchmal die falsche Antwort geben oder eine völlig unerwartete Ausnahme werfen. (Dies war das Verhalten einiger Standardimplementierungen der Enumeration API in frühen Versionen von Java.)

... und unterscheiden sie sich von dem Iterator, den wir für die Sammlung verwenden.

Nein. Das sind Eigenschaften der Iteratoren, die von Standard Collection-Typen implementiert werden; d.h. sie sind entweder "nicht schnell" oder "schwach konsistent" ... wenn sie korrekt in Bezug auf die Synchronisation und das Java-Speichermodell verwendet werden1.


Die Fail-Fast-Iteratoren sind typisch implementiert mit a volatile Zähler auf dem Sammelobjekt.

  • Wenn die Sammlung aktualisiert wird, wird der Zähler erhöht.
  • Wenn ein Iterator erstellt wird, ist der aktuelle Wert des Zählers in den Iterator Objekt.
  • Wenn ein Iterator Wenn die Operation ausgeführt wird, vergleicht die Methode die beiden Zählerwerte und löst einen CME aus, wenn sie unterschiedlich sind.

Die Implementierung von fehlersicheren Iteratoren ist typischerweise gering. Sie beruhen typischerweise auf Eigenschaften der spezifischen Datenstrukturen der Listenimplementierung. Es gibt kein allgemeines Muster. (Lesen Sie den Quellcode für die spezifischen Auflistungsklassen, an denen Sie interessiert sind.)


1 - Der Fahrer ist, dass das Fail-Fast-Verhalten davon ausgeht, dass die Anwendungs-ID in Bezug auf die Synchronisation und das Speichermodell korrekt ist. Das bedeutet zB, wenn Sie iterieren ArrayList Ohne korrekte Synchronisation könnte das Endergebnis ein beschädigtes Listenergebnis sein. Der "Fast fail" -Mechanismus wird wahrscheinlich die gleichzeitige Änderung erkennen (obwohl dies nicht garantiert ist), aber die zugrundeliegende Beschädigung wird nicht erkannt. Als Beispiel, Javadoc zum Vector.iterator() sagt das:

"Das Fail-Fast-Verhalten eines Iterators kann nicht garantiert werden, da es im Allgemeinen unmöglich ist, bei unsynchronisierten simultanen Modifikationen harte Garantien zu geben. Fail-Fast-Iteratoren werfen ConcurrentModificationException auf Best-Effort-Basis. Daher wäre es falsch, ein Programm zu schreiben, das von dieser Ausnahme für seine Korrektheit abhängig ist: Das Fail-Fast-Verhalten von Iteratoren sollte nur zur Erkennung von Fehlern verwendet werden. "


68
2018-06-29 07:09



Sie sind eher fail-schnell und schwach-konsistent Typen:

Iteratoren von java.util Paket werfen ConcurrentModificationException Wenn die Sammlung während des Iterierens durch die Methoden der Sammlung geändert wurde (Hinzufügen / Entfernen)

Iteratoren von java.util.concurrent Paket iteriert in der Regel über einen Snapshot und ermöglicht gleichzeitige Änderungen, aber möglicherweise keine Auflistungsaktualisierungen, nachdem der Iterator erstellt wurde.


30
2018-06-29 06:45



Der einzige Unterschied besteht darin, dass der fehlersichere Iterator im Gegensatz zum Fail-Fasten-Iterator keine Ausnahme auslöst.

Wenn Collection strukturell geändert wird, während ein Thread darüber iteriert. Dies liegt daran, dass sie an der Kopie der Sammlung statt an der ursprünglichen Sammlung arbeiten, weshalb sie als fehlersicherer Iterator bezeichnet werden.

Iterator von CopyOnWriteArrayList ist ein Beispiel für fehlersicheren Iterator auch Iterator geschrieben von ConcurrentHashMap keySet ist auch fehlersicherer Iterator und wirft niemals ConcurrentModificationException in Java.


19
2018-06-29 06:31