W Javie istnieją dwa typy iteratorów: odporne na awarie i szybkie.
Co to oznacza i czy jest między nimi różnica?
W Javie istnieją dwa typy iteratorów: odporne na awarie i szybkie.
Co to oznacza i czy jest między nimi różnica?
Odpowiedzi:
Jaka jest różnica między nimi ...
„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:
„Większość współbieżnych implementacji kolekcji (w tym większość kolejek) również różni się od zwykłych konwencji java.util tym, że ich Iteratory i Spliteratory zapewniają słabo spójne, a nie szybkie przechodzenie po awarii”.
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 Enumerationinterfejsu API we wczesnych wersjach języka Java).
... i czy różnią się od iteratora, którego używamy do zbierania.
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 volatilelicznika w obiekcie kolekcji.
Iteratorutworzeniu aktualna wartość licznika jest osadzana w Iteratorobiekcie.Iteratoroperacji 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ę ArrayListbez 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 for Vector.iterator()mówi tak:
„Fail-fast zachowanie iterator nie może być zagwarantowane, jak to jest, ogólnie rzecz biorąc, niemożliwe, aby jakiekolwiek twarde gwarancje w obecności rozsynchronizowany jednoczesnej modyfikacji. Fail-fast iteratory rzucać
ConcurrentModificationExceptionna zasadzie best-effort. Dlatego byłoby źle napisać program, który zależał od tego wyjątku ze względu na jego poprawność: szybkie działanie iteratorów w przypadku awarii powinno być używane tylko do wykrywania błędów. "
setArraykażdą modyfikację.
Są to typy raczej odporne na awarie i słabo spójne :
Iteratory z java.utilrzutu pakietu, ConcurrentModificationExceptionjeśli kolekcja została zmodyfikowana metodami kolekcji (dodaj / usuń) podczas iteracji
Iteratory z java.util.concurrentpakietu zwykle wykonują iterację po migawce i zezwalają na jednoczesne modyfikacje, ale mogą nie odzwierciedlać aktualizacji kolekcji po utworzeniu iteratora.
Iteratorlub Enumerationokreślić zachowanie jako nie-fast lub fail-safe. To konkretne implementacje (tj. Określone metody kolekcji iterator()/ 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.
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: