2015-06-16 11 views
5

Ho scritto questo esempio a seguito di un concetto di prova ConcurrentModificationException:Perché non il mio campione tiro ConcurrentModificationException

public class Person 
{ 
    String name; 
    public Person(String name) 
    { 
     this.name = name; 
    } 
} 

public static void main(String[] args) 
{ 
    List<Person> l = new ArrayList<Person>(); 
    l.add(new Person("a")); 
    l.add(new Person("b")); 
    l.add(new Person("c")); 

    int i = 0; 
    for(Person s : l) 
    { 
     if(s.name.equals("b")) 
      l.remove(i); 
     i++; 
    } 

    for(Person s : l) 
     System.out.println(s.name); 
} 

Quando ho eseguito il metodo principale sopra, ConcurrentModificationException non ottiene gettati e le stampe console di output il seguente risultato :

a 
c 

By con la mia conoscenza di questo problema, quando in un ciclo per la lista, quando si modifica la lista, un'eccezione ConcurrentModificationException deve essere gettato. Ma perché nel mio esempio non si verifica questo?

+2

Non v'è alcuna garanzia * * che le modifiche strutturali alla lista getteranno un 'ConcurrentModificationException'. – aioobe

+0

Probabilmente a causa dei dettagli di implementazione di ArrayList. Leggi https://stackoverflow.com/questions/18448671/how-to-avoid-concurrentmodificationexception-while-removing-elements-from-arr – Armand

+1

Perché il tuo loop termina subito dopo "remove". Otterrai l'eccezione se aggiungi un quarto elemento dopo "c" o se rimuovi la persona "a". – Marvin

risposta

1

Non esiste la garanzia che le modifiche strutturali all'elenco generano un valore ConcurrentModificationException.

Dal documentation:

noti che sicuro-veloce comportamento non può essere garantita, poiché è, in generale, impossibile fare alcuna garanzia dure in presenza di sincronizzato modifica concorrente. Le operazioni fail-fast generano ConcurrentModificationException in base alle migliori condizioni. Pertanto, sarebbe sbagliato scrivere un programma che dipendesse da questa eccezione per la sua correttezza: ConcurrentModificationException dovrebbe essere usato solo per rilevare i bug.

In questo caso particolare, sei "fortunato" (o "sfortunato" a seconda di come lo vedi). Il cambiamento strutturale passa inosservato poiché il loop esiste prima che venga eseguito un altro controllo di modifica.

Per una spiegazione dettagliata, fare riferimento alle risposte del DUP:

+1

Esiterei a considerare questo come una risposta ... – Marco13

+0

@ Marco13, cosa intendi? Potresti chiarire? La mia risposta mostra che il comportamento aderisce al contratto. – aioobe

+1

Sì, ma non spiega il "perché" in nessuna forma. Certo, mi sarei anche aspettato che si lanciasse. Ad esempio, aggiungi un'altra persona alla lista e poi la lancia. Perché non lo fa per questa particolare configurazione? (Sto attualmente indagando su questa ... una buona domanda IMHO) – Marco13

Problemi correlati