Modo corretto per sincronizzare ArrayList in java

Non sono sicuro se questo è il modo corretto per sincronizzare il mio ArrayList .

Ho un ArrayList in_queue che viene passato dalla funzione registerInQueue .

 ArrayList in_queue = null; public void registerInQueue(ArrayList in_queue) { this.in_queue = in_queue; } 

Ora sto cercando di sincronizzarlo. Questo in_queue mio object in_queue correttamente?

 List in_queue_list = Collections.synchronizedList(in_queue); synchronized (in_queue_list) { while (in_queue_list.size() > 0) { in_queue_list.remove(0); } } 

Si sta sincronizzando due volte, il che è inutile e forse rallenta il codice: le modifiche mentre si scorre sull’elenco richiedono una sincronizzazione sull’intera operazione, che si sta eseguendo con synchronized (in_queue_list) Using Collections.synchronizedList() è superfluo in quel caso (crea un wrapper che sincronizza le singole operazioni).

Tuttavia, dal momento che stai svuotando completamente la lista, la rimozione ripetuta del primo elemento è il peggior modo ansible per farlo, sice per ogni elemento tutti i seguenti elementi devono essere copiati, rendendo questa operazione O (n ^ 2) – orribilmente lento per le liste più grandi.

Invece, chiama semplicemente clear() – non è necessaria alcuna iterazione.

Modifica: se è necessario successivamente la sincronizzazione a metodo singolo di Collections.synchronizedList() , questo è il modo corretto:

 List in_queue_list = Collections.synchronizedList(in_queue); in_queue_list.clear(); // synchronized implicitly, 

Ma in molti casi, la sincronizzazione a metodo singolo è insufficiente (ad esempio per tutta l’iterazione, o quando si ottiene un valore, si eseguono calcoli basati su di esso e lo si sostituisce con il risultato). In tal caso, devi comunque utilizzare la sincronizzazione manuale, quindi Collections.synchronizedList() è solo un inutile sovraccarico.

Guardando il tuo esempio, penso che ArrayBlockingQueue (oi suoi fratelli) possa essere utile. Si occupano della sincronizzazione per te, così i thread possono scrivere in coda o dare un’occhiata / prendere senza ulteriori interventi di sincronizzazione da parte tua.

È corretto e documentato:

http://java.sun.com/javase/6/docs/api/java/util/Collections.html#synchronizedList(java.util.List)

Tuttavia, per cancellare l’elenco, chiama semplicemente List.clear () .

Sì, è il modo corretto, ma è necessario il blocco sincronizzato se si desidera che tutte le rimozioni siano sicure – a meno che la coda non sia vuota, non sono ammesse rimozioni. La mia ipotesi è che si desidera solo eseguire operazioni di coda e dequeue sicure, in modo da poter rimuovere il blocco sincronizzato.

Tuttavia, esistono code simultanee molto avanzate in Java come ConcurrentLinkedQueue

Prendiamo un elenco normale (implementato dalla class ArrayList) e rendilo sincronizzato. Questo è mostrato nella class SynchronizedListExample. Passiamo il metodo Collections.synchronizedList a una nuova ArrayList of Strings. Il metodo restituisce un elenco di stringhe sincronizzato. // Ecco la class SynchronizedArrayList

 package com.mnas.technology.automation.utility; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.apache.log4j.Logger; /** * * @author manoj.kumar * @email kumarmanoj.mtech@gmail.com * */ public class SynchronizedArrayList { static Logger log = Logger.getLogger(SynchronizedArrayList.class.getName()); public static void main(String[] args) { List synchronizedList = Collections.synchronizedList(new ArrayList()); synchronizedList.add("Aditya"); synchronizedList.add("Siddharth"); synchronizedList.add("Manoj"); // when iterating over a synchronized list, we need to synchronize access to the synchronized list synchronized (synchronizedList) { Iterator iterator = synchronizedList.iterator(); while (iterator.hasNext()) { log.info("Synchronized Array List Items: " + iterator.next()); } } } } 

Si noti che durante l’iterazione sull’elenco, questo accesso viene comunque eseguito utilizzando un blocco sincronizzato che blocca l’object synchronizedList. In generale, l’iterazione su una collezione sincronizzata dovrebbe essere eseguita in un blocco sincronizzato