2013-07-25 14 views

risposta

74

Come indicato su questo link:

CopyOnWriteArrayList è una classe Collection concomitante introdotto in Java 5 Concorrenza API insieme a suo cugino popolare ConcurrentHashMap in Java.

CopyOnWriteArrayList implementa l'interfaccia Elenco come ArrayList, Vector e LinkedList ma è una raccolta thread-safe e raggiunge la sicurezza del thread in un modo leggermente diverso rispetto a Vector o ad altre classi di raccolta thread-safe.

Come nome suggerisce CopyOnWriteArrayList crea copia del sottostante ArrayList ad ogni operazione di mutazione per esempio aggiungi o imposta. Normalmente CopyOnWriteArrayList è molto costoso perché comporta una copia costosa di di array con ogni operazione di scrittura ma è molto efficiente se si dispone di un elenco in cui Iterazione supera la mutazione ad es. per lo più è necessario iterare ArrayList e non modificarlo troppo spesso.

Iterator di CopyOnWriteArrayList è fail-safe e non genera ConcurrentModificationException anche se alla base CopyOnWriteArrayList viene modificata una volta iterazione inizia perché Iterator sta operando sulla copia separata di ArrayList. Di conseguenza, tutti gli aggiornamenti effettuati su CopyOnWriteArrayList non sono disponibili su Iterator .

per ottenere la versione più aggiornata fare una nuova lettura come list.iterator();

Detto questo, aggiornando questa collezione un sacco ucciderà prestazioni. Se si è tentato di ordinare un oggetto CopyOnWriteArrayList, verrà visualizzato un oggetto UsupportedOperationException (il richiamo dell'ordinamento impostato sulla raccolta N volte). Dovresti usare questa lettura solo quando stai facendo più di 90 +% di letture.

+0

E se è necessario aggiungere elementi molto frequentemente all'elenco e talvolta è necessario rimuovere tutto. Pensi che la via "sincronizzata" sia l'approccio migliore? –

+2

È possibile considerare il pacchetto 'java.util.concurrent' su' Collections.synchronizedList'. –

+0

Lo sto già usando. Ma sembra funzionare solo quando combino con la vecchia parola chiave 'sincronizzata'. –

20

Qual è lo scopo di gestire un nuovo array?

La copia dell'array sottostante garantisce che qualsiasi iterazione della struttura dati sia sicura mentre l'iterazione si sta verificando su uno "snapshot" essenzialmente immutabile dei dati.

È per gli altri thread leggere l'array?

Sort of. Più specificamente, è per ogni thread essere in grado di iterare l'array in tutta sicurezza senza timore di uno ConcurrentModificationException o di altro comportamento sconosciuto/non definito.

Quindi, se un sistema è in concorrenza elevata e la maggior parte delle azioni dei thread non sta leggendo, è meglio usare CopyOnWriteArrayList. Ho ragione?

No. Solo se la maggior parte delle azioni dei thread sono iterazioni nell'elenco. Se la maggior parte delle attività sono letture basate su accessi casuali, un ReadWriteLock potrebbe essere migliore.

Dal javadoc di CopyOnWriteArrayList

Questo è di solito troppo costoso, ma può essere più efficiente rispetto alle alternative quando attraversamento operazioni di gran lunga più numerosi mutazioni, ed è utile quando non si può o non si vuole sincronizzare attraversamenti, ma devono precludere l'interferenza tra thread concorrenti.

+0

potresti spiegare perché 'ReadWriteLock' potrebbe essere migliore? – damluar

+4

Poiché 'CopyOnWriteArrayList' è per gli attraversamenti sicuri. Il costo del suo utilizzo è la duplicazione della matrice sottostante di riferimenti per ciascuna modifica e probabilmente il mantenimento di più copie per i thread che iterano su versioni obsolete della struttura. Un 'ReadWriteLock' consentirebbe a più lettori e consentirebbe allo scrittore occasionale di apportare le modifiche necessarie. –

Problemi correlati