it-swarm.com.de

Was sind ausfallsichere und ausfallsichere Iteratoren in Java

In Java gibt es zwei Arten von Iteratoren: ausfallsicher und ausfallsicher.

Was bedeutet das und ist der Unterschied zwischen ihnen?

95
Prateek

Was ist der Unterschied zwischen ihnen ...

"Fail safe" bedeutet: es wird nicht scheitern. Genau genommen gibt es in Java als ausfallsicherer Iterator kein solches . Der korrekte Begriff lautet "schwach" konsistent ". Der Javadoc sagt:

"Die meisten gleichzeitigen Auflistungsimplementierungen (einschließlich der meisten Warteschlangen) unterscheiden sich auch von den üblichen Java.util-Konventionen darin, dass ihre Iteratoren und Spliteratoren eher eine schwach konsistente als eine schnell fehlgeschlagene Überquerung bieten."

Schwache Konsistenz bedeutet in der Regel, dass die Garantien für das, was die Iteration sieht, schwächer sind, wenn eine Sammlung gleichzeitig mit einer Iteration geändert wird. (Die Details werden in den Javadocs der jeweiligen Sammlungsklassen angegeben.)

"Schnell fehlschlagen" bedeutet: Es kann fehlschlagen ... und der Fehlerzustand wird aggressiv überprüft, so dass der Fehlerzustand (soweit möglich) vorliegt1) erkannt , bevor Schaden angerichtet werden kann. In Java schlägt ein ausfallsicherer Iterator fehl, indem ein ConcurrentModificationException ausgelöst wird.

Die Alternative zu "ausfallsicher" und "schwach konsistent" ist die Semantik, bei der die Iteration unvorhersehbar fehlschlägt. z.B. manchmal die falsche Antwort geben oder eine unerwartete Ausnahme auslösen. (Dies war das Verhalten einiger Standardimplementierungen der API Enumeration in früheren Versionen von Java.)

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

Nein. Dies sind Eigenschaften der Iteratoren, die von standardmäßigen Auflistungstypen implementiert werden. d.h. sie sind entweder "schnell fehlgeschlagen" oder "schwach konsistent" ..., wenn sie in Bezug auf die Synchronisation und das Java Speichermodell korrekt verwendet werden1.


Die Fail-Fast-Iteratoren werden normalerweise mithilfe eines volatile -Zählers auf dem Auflistungsobjekt implementiert.

  • Wenn die Sammlung aktualisiert wird, wird der Zähler inkrementiert.
  • Wenn ein Iterator erstellt wird, wird der aktuelle Wert des Zählers in das Objekt Iterator eingebettet.
  • Wenn eine Iterator -Operation ausgeführt wird, vergleicht die Methode die beiden Zählerwerte und löst eine CME aus, wenn sie unterschiedlich sind.

Die Implementierung von ausfallsicheren Iteratoren ist typischerweise leicht. Sie stützen sich normalerweise auf Eigenschaften der Datenstrukturen der spezifischen Listenimplementierung. Es gibt kein allgemeines Muster. (Lesen Sie den Quellcode für die jeweiligen Sammlungsklassen, an denen Sie interessiert sind.)


1 - Der Fahrer geht davon aus, dass das Fail-Fast-Verhalten die Anwendungs-ID in Bezug auf die Synchronisation und das Speichermodell korrekt angibt. Das bedeutet, dass (zum Beispiel) wenn Sie ein ArrayList ohne ordnungsgemäße Synchronisation durchlaufen, das Ergebnis möglicherweise ein beschädigtes Listenergebnis ist. Der "Fast Fail" -Mechanismus erkennt wahrscheinlich die gleichzeitige Änderung (obwohl dies nicht garantiert ist), erkennt jedoch nicht die zugrunde liegende Beschädigung. Als Beispiel sagt javadoc für Vector.iterator() Folgendes:

"Das Fail-Fast-Verhalten eines Iterators kann nicht garantiert werden, da es im Allgemeinen unmöglich ist, bei nicht synchronisierten gleichzeitigen Änderungen harte Garantien zu geben. Fail-Fast-Iteratoren werfen ConcurrentModificationException auf bestmöglicher Basis Es wäre daher falsch, ein Programm zu schreiben, dessen Korrektheit von dieser Ausnahme abhängt: Das Fail-Fast-Verhalten von Iteratoren sollte nur zum Erkennen von Fehlern verwendet werden. "

80
Stephen C

Es handelt sich eher um ausfallsicher und schwach konsistent Typen:

Iteratoren von Java.util package throw ConcurrentModificationException, wenn die Auflistung durch die Methoden der Auflistung (Hinzufügen/Entfernen) während der Iteration geändert wurde

Iteratoren von Java.util.concurrent package iteriert normalerweise über einen Snapshot und lässt gleichzeitige Änderungen zu, spiegelt jedoch möglicherweise keine Sammlungsaktualisierungen wider, nachdem der Iterator erstellt wurde.

40

Der einzige Unterschied ist, dass der ausfallsichere Iterator im Gegensatz zum ausfallsicheren Iterator keine Ausnahme auslöst.

Wenn Collection strukturell geändert wird, während ein Thread darüber iteriert. Dies liegt daran, dass sie mit dem Klon der Sammlung anstelle der ursprünglichen Sammlung arbeiten. Aus diesem Grund werden sie als ausfallsichere Iteratoren bezeichnet.

Der Iterator von CopyOnWriteArrayList ist ein Beispiel für einen ausfallsicheren Iterator. Der von ConcurrentHashMap keySet geschriebene Iterator ist auch ein ausfallsicherer Iterator und löst in Java niemals eine ConcurrentModificationException aus.

22
Juned Ahsan