2012-01-05 8 views

risposta

12

Fail-fast significa che quando si tenta di modificare il contenuto quando si sta iterando attraverso di esso, fallirà e si genererà ConcurrentModificationException.

Set keys = hashMap.keySet(); 
for (Object key : keys) { 
    hashMap.put(someObject, someValue); //it will throw the ConcurrentModificationException here 
} 

Per HashTable enumerazione:

Enumeration keys = hashTable.keys(); 
while (keys.hasMoreElements()) { 
      hashTable.put(someKey, someValue); //this is ok 
    } 
+3

Gli iteratori di Hastable sono veloci. Le sue enumerazioni non lo sono. –

+0

Hai ragione! Grazie! – evanwong

3

Quando si chiama iterator.next(), se sono state apportate modifiche tra il momento in cui è stato creato l'iteratore e viene chiamato l'ora next(), viene lanciata immediatamente una ConcurrentModificationException. Questo è ciò che significa fail-fast.

Le enumerazioni restituite da Hashtable non hanno questo comportamento. Assumono che tu sappia cosa stai facendo e il loro comportamento, AFAIK, non è definito se modifichi la mappa mentre la itererai su una delle sue enumerazioni.

3

Il modo migliore è probabilmente esaminare l'origine per ogni classe implementata dall'implementazione Open JDK per ogni classe; in questo modo, puoi ottenere la risposta direttamente dalla bocca del cavallo :-)

A parte questo, in sostanza, "fail-fast" in questo senso significa che un Iterator su una HashMap genererà un'eccezione se rileva che un altro thread ha modificato la HashMap di destinazione: se si guarda nel sorgente per HashMap, si vedrà ciò facendo semplicemente controllando un contatore per il numero di modifiche previste. Se il conteggio delle modifiche è diverso dall'Iteratore previsto, significa che qualcun altro è entrato dall'ultimo controllo e ha incasinato la HashMap, quindi l'Iterator genera uno ConcurrentModificationException.

Un Iterator "non fail-fast" non si preoccuperebbe di controllare, e passerà felicemente al suo business nella struttura dati sottostante. Pertanto, si ottiene una certa flessibilità (probabilmente dubbia flessibilità in questo caso) in cambio di possibili errori successivi; ad esempio tentando di accedere a un valore che non è più presente.

Come per tutte le strategie fail-fast, l'idea è che prima viene rilevato un errore, più è facile il ripristino o il debug.

+3

Non solo un altro thread. Se modifichi la mappa mentre esegui un'iterazione su di essa, anche nella stessa discussione, viene generata una ConcurrentModification (eccetto se usi l'iteratore stesso per modificare la mappa) –

+0

Molto vero! Un errore a volte confuso che ho fatto io stesso :-) –

Problemi correlati