PDA

View Full Version : [java] lanciare ConcurrentModificationException


gfburgio88
18-01-2009, 12:42
Salve a tutti,
sto realizzando una struttura dati che devve essere possibile iterare.
Il problema sta appunto nella realizzazione dell'iteratore, in quanto dovrebbe lanciare ConcurrentModificationException se la struttura dati viene modificata da un'altro thread mentre si sta iterando la struttura. grazie e spero di essere stato chiaro

fero86
18-01-2009, 14:45
Salve a tutti,
sto realizzando una struttura dati che devve essere possibile iterare.
Il problema sta appunto nella realizzazione dell'iteratore, in quanto dovrebbe lanciare ConcurrentModificationException se la struttura dati viene modificata da un'altro thread mentre si sta iterando la struttura. grazie e spero di essere stato chiaro non da un altro thread: la ConcurrentModificationException viene lanciata semplicemente se si cerca di modificare la collezione mentre c'é un'iterazione in corso, indipendentemente dal thread che tenta la modifica. quando c'é un'iterazione in corso la collezione puó essere modificata solo dall'iteratore che sta iterando. il meccanismo di fail-fast delle collections di Java é volutamente approssimativo, infatti la ConcurrentModificationException non é indice di errore di sincronizzazione e non dovrebbe mai essere catturata (come tutte le eccezioni unchecked), ma semplicemente osservata dal programmatore in fase di debug come diagnostica.

l'implementazione é molto semplice: tutti i metodi che in qualche modo modificano la collection devono come prima cosa controllare se c'é un'iterazione in corso (usa un flag, quello che ti pare) ed in tal caso lanciare l'eccezione. spero di ricordarmi correttamente i dettagli del contratto.

andbin
18-01-2009, 18:13
l'implementazione é molto semplice: tutti i metodi che in qualche modo modificano la collection devono come prima cosa controllare se c'é un'iterazione in corso (usa un flag, quello che ti pare) ed in tal caso lanciare l'eccezione. spero di ricordarmi correttamente i dettagli del contratto.A dire il vero le specifiche (di ConcurrentModificationException) non dicono affatto come debba essere realmente implementata la determinazione della modifica.
E come hai detto tu, cioè ogni operazione di modifica va a controllare se c'è una iterazione in corso, non è praticabile/utile. Le collezioni standard di Java SE usano una tecnica molto semplice: ogni collezione ha un campo interno modCount (int) e ogni operazione di modifica diretta sulla collezione lo incrementa. Quando un iteratore viene istanziato, l'iteratore si copia il valore di modCount in un suo campo interno. Quando un next/remove viene invocato sull'iteratore, vengono confrontati i due modCount collezione vs iteratore. Se uguali ok, se diversi la collezione è stata modificata, quindi ConcurrentModificationException.