Fail-Safe-Iterator vs. Fail-Fast-Iterator

Fail-Safe-Iterator gegen Fail-Fast-Iterator

1. Einführung

In diesem Artikel stellen wir das Konzept von Fail-Fast und Fail-SafeIteratorsvor.

Fail-Fast-Systeme brechen den Betrieb so schnell wie möglich ab, wodurch Fehler sofort aufgedeckt und der gesamte Betrieb gestoppt werden.

Fail-Safe systems don’t abort an operation in the case of a failure. Such systems try to avoid raising failures as much as possible.

2. Fail-FastIterators

Fail-Fast-Iteratoren in Java spielen nicht mit, wenn die zugrunde liegende Sammlung geändert wird.

Collections unterhalten einen internen Zähler namensmodCount. Jedes Mal, wenn ein Element zuCollectionhinzugefügt oder entfernt wird, wird dieser Zähler erhöht.

Bei der Iteration wird bei jedem Aufruf vonnext() der aktuelle Wert vonmodCount mit dem Anfangswert verglichen. Wenn eine Nichtübereinstimmung vorliegt, wirdConcurrentModificationException ausgelöst, wodurch der gesamte Vorgang abgebrochen wird.

Standarditeratoren fürCollections vonjava.util package wieArrayList,HashMap usw. sind Fail-Fast.

ArrayList numbers = // ...

Iterator iterator = numbers.iterator();
while (iterator.hasNext()) {
    Integer number = iterator.next();
    numbers.add(50);
}

Im obigen Code-Snippet wirdConcurrentModificationException zu Beginn eines nächsten Iterationszyklus ausgelöst, nachdem die Änderung durchgeführt wurde.

Das Fail-Fast-Verhalten kann nicht in allen Szenarien garantiert werden, da es unmöglich ist, das Verhalten bei gleichzeitigen Änderungen vorherzusagen. These iterators throw ConcurrentModificationException on a best effort basis.

Wenn während der Iteration überCollection,an item is removed using Iterator‘s remove() method, that’s entirely safe and doesn’t throw an exception.

Wenn jedoch dieremove()-Methode vonCollectionzum Entfernen eines Elements verwendet wird, wird eine Ausnahme ausgelöst:

ArrayList numbers = // ...

Iterator iterator = numbers.iterator();
while (iterator.hasNext()) {
    if (iterator.next() == 30) {
        iterator.remove(); // ok!
    }
}

iterator = numbers.iterator();
while (iterator.hasNext()) {
    if (iterator.next() == 40) {
        numbers.remove(2); // exception
    }
}

3. Ausfallsichere Iteratoren

Fail-Safe-Iteratoren bevorzugen das Fehlen von Fehlern gegenüber der unpraktischen Ausnahmebehandlung.

Diese Iteratoren erstellen einen Klon der tatsächlichenCollection und iterieren darüber. Wenn nach dem Erstellen des Iterators Änderungen vorgenommen werden, bleibt die Kopie weiterhin unberührt. Daher durchlaufen dieseIterators weiterhin dieCollection, selbst wenn sie geändert wurden.

Es ist jedoch wichtig, sich daran zu erinnern, dass es keinen wirklich ausfallsicheren Iterator gibt. Der korrekte Begriff lautet Schwach konsistent.

Das heißt,if aCollection is modified while being iterated over, what the Iterator sees is weakly guaranteed. Dieses Verhalten kann für verschiedeneCollections unterschiedlich sein und ist in Javadocs für jeden dieserCollection dokumentiert.

Die Fail-SafeIteratorshaben jedoch einige Nachteile. Ein Nachteil ist, dassIterator isn’t guaranteed to return updated data from the Collection auf dem Klon anstelle der tatsächlichenCollection funktioniert.

Ein weiterer Nachteil ist der Aufwand beim Erstellen einer Kopie derCollection, sowohl in Bezug auf Zeit als auch auf Speicher.

Iterators aufCollections ausjava.util.concurrent Paket wieConcurrentHashMap,CopyOnWriteArrayList usw. sind von Natur aus ausfallsicher.

ConcurrentHashMap map = new ConcurrentHashMap<>();

map.put("First", 10);
map.put("Second", 20);
map.put("Third", 30);
map.put("Fourth", 40);

Iterator iterator = map.keySet().iterator();

while (iterator.hasNext()) {
    String key = iterator.next();
    map.put("Fifth", 50);
}

Im obigen Code-Snippet verwenden wir Fail-SafeIterator. Daher wird, obwohl während der Iteration ein neues Element zuCollection hinzugefügt wird, keine Ausnahme ausgelöst.

Der Standarditerator_ for the _ConcurrentHashMap ist schwach konsistent. Dies bedeutet, dass dieseIterator gleichzeitige Modifikationen tolerieren können, Elemente durchlaufen, wie sie zum Zeitpunkt der Erstellung vonIterator vorhanden waren, und möglicherweise Änderungen anCollection nach der Erstellung von ((aber nicht garantiert)) widerspiegeln dieIterator.

Daher wird im obigen Code-Snippet die Iteration fünfmal wiederholt, wasit does detect the newly added element to the Collection. bedeutet

4. Fazit

In diesem Tutorial haben wir gesehen, was Fail-Safe und Fail-FastIteratorsbedeuten und wie diese in Java implementiert sind.

Der vollständige Code in diesem Artikel ist inover on GitHub verfügbar.