Esistono due tipi di iteratori in Java: fail-safe e fail-fast.
Cosa significa, ed è la differenza tra loro?
Esistono due tipi di iteratori in Java: fail-safe e fail-fast.
Cosa significa, ed è la differenza tra loro?
Risposte:
Qual'è la differenza tra loro ...
"Fail-safe" ( in ingegneria ) significa che qualcosa si guasta in un modo che non causa danni minimi o nulli. A rigor di termini, non esiste in Java un iteratore a prova di errore. Se un iteratore fallisce (nel senso normale di "fail"), ci si può aspettare che si verifichi un danno.
Sospetto che in realtà intendi iteratori "debolmente coerenti". Il javadoc dice:
"La maggior parte delle implementazioni di Collection simultanee (inclusa la maggior parte delle code) differiscono anche dalle consuete convenzioni java.util in quanto i loro iteratori e spliteratori forniscono un attraversamento debolmente coerente piuttosto che un rapido errore."
Tipicamente, consistenza debole significa che se una raccolta viene modificata contemporaneamente a un'iterazione, le garanzie di ciò che vede l'iterazione sono più deboli. (I dettagli verranno specificati in ogni javadocs delle classi di raccolta simultanee.)
"Fail-fast" ( nella progettazione dei sistemi ) significa che la condizione di guasto viene controllata in modo aggressivo in modo che la condizione di guasto venga rilevata (dove possibile 1 ) prima che si possa causare un danno eccessivo. In Java, un iteratore fail-fast fallisce lanciando un file ConcurrentModificationException
.
L'alternativa a "fail-fast" e "debolmente coerente" è semantica in cui l'iterazione fallisce in modo imprevedibile; ad esempio, a volte dare la risposta sbagliata o lanciare un'eccezione inaspettata. (Questo era il comportamento di alcune implementazioni standard Enumeration
dell'API nelle prime versioni di Java.)
... e sono diversi dall'iteratore che usiamo per la raccolta.
No. Queste sono proprietà degli iteratori implementati dai tipi Collection standard; cioè sono "fail fast" o "debolmente consistenti" ... se usati correttamente rispetto alla sincronizzazione e al modello di memoria Java 1 .
Gli iteratori fail-fast vengono in genere implementati utilizzando un volatile
contatore sull'oggetto di raccolta.
Iterator
viene creato un, il valore corrente del contatore viene incorporato Iterator
nell'oggetto.Iterator
viene eseguita un'operazione, il metodo confronta i due valori del contatore e lancia un CME se sono diversi.Al contrario, gli iteratori debolmente coerenti sono in genere leggeri e sfruttano le proprietà delle strutture di dati interne di ciascuna raccolta simultanea. Non esiste uno schema generale. Se sei interessato, leggi il codice sorgente per diverse classi di raccolta.
1 - Il pilota è che il comportamento veloce presuppone che l'applicazione id correttamente rispetto alla sincronizzazione e al modello di memoria. Ciò significa che (ad esempio) se si esegue un'iterazione ArrayList
senza una corretta sincronizzazione, il risultato potrebbe essere un risultato di elenco danneggiato. Il meccanismo "fast fail" rileverà probabilmente la modifica simultanea (sebbene ciò non sia garantito), ma non rileverà il danneggiamento sottostante. Ad esempio, javadoc per Vector.iterator()
dice questo:
"Il comportamento fail-fast di un iteratore non può essere garantito poiché è, in generale, impossibile fornire garanzie concrete in presenza di modifiche simultanee non sincronizzate. Gli iteratori fail-fast eseguono
ConcurrentModificationException
il massimo sforzo. Pertanto, sarebbe sbagliato scrivere un programma che dipendeva da questa eccezione per la sua correttezza: il comportamento veloce degli iteratori dovrebbe essere usato solo per rilevare i bug. "
setArray
qualsiasi modifica.
Sono tipi piuttosto veloci e debolmente coerenti :
Iteratori dal java.util
lancio del pacchetto ConcurrentModificationException
se la raccolta è stata modificata dai metodi della raccolta (aggiungi / rimuovi) durante l'iterazione
Gli iteratori del java.util.concurrent
pacchetto in genere eseguono l'iterazione su un'istantanea e consentono modifiche simultanee ma potrebbero non riflettere gli aggiornamenti della raccolta dopo la creazione dell'iteratore.
Iterator
o Enumeration
specificare il comportamento come fail-fast o fail-safe. Sono implementazioni specifiche (cioè i metodi di raccolta iterator()
/ elements()
etc specifici che restituiscono questi oggetti) che specificano il comportamento. 2) Le implementazioni tipiche dell'enumerazione non sono né a prova di errore né a prova di errore .
L'unica differenza è che l'iteratore fail-safe non genera alcuna eccezione, contrariamente all'iteratore fail-fast.
Se Collection viene modificato strutturalmente mentre un thread sta iterando su di esso. Questo perché funzionano sul clone di Collection anziché sulla raccolta originale ed è per questo che sono chiamati iteratori fail-safe.
L'iteratore di CopyOnWriteArrayList è un esempio di Iteratore fail-safe anche l'iteratore scritto da ConcurrentHashMap keySet è anche un iteratore fail-safe e non lancia mai ConcurrentModificationException in Java.
Questo scenario si riferisce alla "elaborazione simultanea", significa che più di un utente accede alla stessa risorsa. In tale situazione, uno degli utenti tenta di modificare quella risorsa che causa la "ConcurrentProcessingException" perché in quel caso l'altro utente ottiene dati non corretti. Entrambi questo tipo si riferiscono a questo tipo di situazione.
In termini semplici,
Fail-Fast:
A prova di errore: