W Javie istnieją dwa typy iteratorów: odporne na awarie i szybkie.
Co to oznacza i czy jest między nimi różnica?
java
iterator
terminology
Prateek
źródło
źródło
Odpowiedzi:
„Bezawaryjny” ( w inżynierii ) oznacza, że coś zawodzi w sposób, który nie powoduje żadnych szkód lub jest ich minimalny. Ściśle mówiąc, w Javie nie ma czegoś takiego jak iterator odporny na awarie. Jeśli iterator zawiedzie (w normalnym znaczeniu „niepowodzenie”), można spodziewać się uszkodzenia.
Podejrzewam, że w rzeczywistości masz na myśli „słabo spójne” iteratory. Javadoc mówi:
Zwykle słaba spójność oznacza, że jeśli kolekcja jest modyfikowana jednocześnie z iteracją, gwarancje tego, co widzi iteracja, są słabsze. (Szczegóły zostaną określone w każdej z równoległych klas kolekcji javadocs).
„Odporność na awarię ” ( w projektowaniu systemów ) oznacza, że stan awarii jest sprawdzany agresywnie, tak aby stan awarii był (tam, gdzie to możliwe 1 ) wykrywany, zanim możliwe będzie spowodowanie zbyt dużego uszkodzenia. W Javie iterator działający bezawaryjnie zawodzi, rzucając plik
ConcurrentModificationException
.Alternatywa dla „szybkich niepowodzeń” i „słabo spójnych” jest semantyczna, gdy iteracja kończy się niepowodzeniem w nieprzewidywalny sposób; np. aby czasami udzielić złej odpowiedzi lub rzucić nieoczekiwany wyjątek. (Tak było w przypadku niektórych standardowych implementacji
Enumeration
interfejsu API we wczesnych wersjach języka Java).Nie. To są właściwości iteratorów implementowanych przez standardowe typy kolekcji; tzn. są albo „szybko nieudane”, albo „słabo spójne”… jeśli są używane poprawnie w odniesieniu do synchronizacji i modelu pamięci Java 1 .
Iteratory odporne na awarie są zwykle implementowane przy użyciu
volatile
licznika w obiekcie kolekcji.Iterator
utworzeniu aktualna wartość licznika jest osadzana wIterator
obiekcie.Iterator
operacji metoda porównuje dwie wartości liczników i zgłasza CME, jeśli są różne.Z drugiej strony, słabo spójne iteratory są zwykle lekkie i wykorzystują właściwości wewnętrznych struktur danych każdej współbieżnej kolekcji. Nie ma ogólnego wzoru. Jeśli jesteś zainteresowany, przeczytaj kod źródłowy dla różnych klas kolekcji.
1 - Kierowca jest taki, że zachowanie bezawaryjne zakłada, że aplikacja jest poprawnie identyfikowana w odniesieniu do synchronizacji i modelu pamięci. Oznacza to, że (na przykład) jeśli wykonasz iterację
ArrayList
bez prawidłowej synchronizacji, wynikiem może być uszkodzony wynik listy. Mechanizm „szybkiego niepowodzenia” prawdopodobnie wykryje równoczesną modyfikację (chociaż nie jest to gwarantowane), ale nie wykryje podstawowego uszkodzenia. Na przykład javadoc forVector.iterator()
mówi tak:źródło
setArray
każdą modyfikację.Są to typy raczej odporne na awarie i słabo spójne :
Iteratory z
java.util
rzutu pakietu,ConcurrentModificationException
jeśli kolekcja została zmodyfikowana metodami kolekcji (dodaj / usuń) podczas iteracjiIteratory z
java.util.concurrent
pakietu zwykle wykonują iterację po migawce i zezwalają na jednoczesne modyfikacje, ale mogą nie odzwierciedlać aktualizacji kolekcji po utworzeniu iteratora.źródło
Iterator
lubEnumeration
określić zachowanie jako nie-fast lub fail-safe. To konkretne implementacje (tj. Określone metody kolekcjiiterator()
/elements()
etc, które zwracają te obiekty) określają zachowanie. 2) Typowe implementacje wyliczania nie są ani odporne na awarie, ani bezpieczne .Jedyną różnicą jest to, że iterator odporny na awarie nie zgłasza żadnego wyjątku, w przeciwieństwie do iteratora odpornego na awarie.
Jeśli Collection jest modyfikowana strukturalnie, podczas gdy jeden wątek jest nad nią iterowany. Dzieje się tak, ponieważ pracują na klonie kolekcji zamiast oryginalnej kolekcji i dlatego są nazywane iteratorami odpornymi na awarie.
Iterator CopyOnWriteArrayList jest przykładem odpornego na awarie Iteratora, a także iteratora napisanego przez ConcurrentHashMap keySet jest również iteratorem bezpiecznym i nigdy nie rzuca ConcurrentModificationException w Javie.
źródło
Ten scenariusz dotyczy „przetwarzania współbieżnego”, co oznacza, że więcej niż jeden użytkownik uzyskuje dostęp do tego samego zasobu. W takiej sytuacji jeden z użytkowników próbuje zmodyfikować ten zasób, co powoduje „ConcurrentProcessingException”, ponieważ w takim przypadku inny użytkownik otrzymuje nieprawidłowe dane. Oba te typy odnoszą się do tego rodzaju sytuacji.
Krótko mówiąc,
Szybka awaria:
Bezpieczny:
źródło