Fail-Safe Iterator versus Fail-Fast Iterator

1. Inleiding

In dit artikel introduceren we het concept van Fail-Fast en Fail-Safe Iteratoren.

Fail-Fast-systemen breken de werking zo snel mogelijk af, waardoor storingen onmiddellijk worden blootgelegd en de hele operatie wordt stopgezet.

Terwijl, Fail-Safe-systemen breken een bewerking niet af in het geval van een storing. Dergelijke systemen proberen zoveel mogelijk storingen te voorkomen.

2. Fail-Fast Iteratoren

Fail-fast iterators in Java spelen niet mee wanneer de onderliggende collectie wordt gewijzigd.

Collecties een interne teller onderhouden modCount. Elke keer dat een item wordt toegevoegd aan of verwijderd uit het Verzameling, wordt deze teller opgehoogd.

Bij iteratie, op elk De volgende() call, de huidige waarde van modCount wordt vergeleken met de oorspronkelijke waarde. Als er een mismatch is, gooit het ConcurrentModificationException waardoor de hele operatie wordt afgebroken.

Standaard iteratoren voor Collecties van java.util-pakket zoals ArrayList, Hash kaart, enz. zijn Fail-Fast.

ArrayList numbers = // ... Iterator iterator = numbers.iterator (); while (iterator.hasNext ()) {Geheel getal = iterator.next (); numbers.add (50); }

In het bovenstaande codefragment is de ConcurrentModificationException wordt aan het begin van een volgende iteratiecyclus gegooid nadat de wijziging is uitgevoerd.

Het Fail-Fast-gedrag is niet gegarandeerd in alle scenario's, omdat het onmogelijk is om gedrag te voorspellen in geval van gelijktijdige wijzigingen. Deze iterators gooien ConcurrentModificationException op een best mogelijke basis.

Als tijdens iteratie over een Verzameling, een item wordt verwijderd met Iterator‘S verwijderen() methode, dat is volkomen veilig en genereert geen uitzondering.

Als het Verzameling‘S verwijderen() methode wordt gebruikt voor het verwijderen van een element, het genereert een uitzondering:

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); // uitzondering}}

3. Faalveilige iteratoren

Fail-Safe iterators geven de voorkeur aan het ontbreken van fouten boven het ongemak van het afhandelen van uitzonderingen.

Die iteratoren creëren een kloon van het werkelijke Verzameling en herhaal erover. Als er een wijziging plaatsvindt nadat de iterator is gemaakt, blijft de kopie onaangeroerd. Vandaar deze Iteratoren blijf een lus maken over de Verzameling zelfs als het is gewijzigd.

Het is echter belangrijk om te onthouden dat er niet zoiets bestaat als een echte Fail-Safe-iterator. De juiste term is zwak consistent.

Dat betekent, als eenVerzameling wordt gewijzigd terwijl het wordt herhaald, wat de Iterator ziet is zwak gegarandeerd. Dit gedrag kan verschillend zijn voor verschillende Collecties en is gedocumenteerd in Javadocs van elk van deze Verzameling.

De Fail-Safe Iteratoren hebben echter een paar nadelen. Een nadeel is dat de Iterator kan niet gegarandeerd bijgewerkte gegevens retourneren van de Verzameling, omdat het aan de kloon werkt in plaats van aan de werkelijke Verzameling.

Een ander nadeel is de overhead voor het maken van een kopie van het Verzameling, zowel wat betreft tijd als geheugen.

Iteratoren Aan Collecties van java.util.concurrent pakket zoals ConcurrentHashMap, CopyOnWriteArrayList, enz. zijn Fail-Safe van aard.

ConcurrentHashMap map = nieuwe ConcurrentHashMap (); map.put ("First", 10); map.put ("Second", 20); map.put ("Derde", 30); map.put ("Vierde", 40); Iterator iterator = map.keySet (). Iterator (); while (iterator.hasNext ()) {String key = iterator.next (); map.put ("Vijfde", 50); }

In het bovenstaande codefragment gebruiken we Fail-Safe Iterator. Dus ook al wordt er een nieuw element toegevoegd aan de Verzameling tijdens de iteratie genereert het geen uitzondering.

De standaard iteratorvoor de ConcurrentHashMap is zwak consistent. Dit betekent dat dit Iterator kan gelijktijdige wijziging tolereren, doorloopt elementen zoals ze toen bestonden Iterator is geconstrueerd en kan (maar is niet gegarandeerd) wijzigingen in het Verzameling na de bouw van de Iterator.

Daarom wordt in het bovenstaande codefragment de iteratie vijf keer herhaald, wat betekent het detecteert het nieuw toegevoegde element aan het Verzameling.

4. Conclusie

In deze tutorial hebben we gezien wat Fail-Safe en Fail-Fast Iteratoren bedoel en hoe deze worden geïmplementeerd in Java.

De volledige code die in dit artikel wordt gepresenteerd, is beschikbaar op GitHub.