Forma correcta de sincronizar ArrayList en Java

No estoy seguro de si esta es la forma correcta de sincronizar mi ArrayList .

Tengo una ArrayList in_queue que se transfiere desde la función registerInQueue .

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

Ahora estoy tratando de sincronizarlo. ¿Esto está sincronizando correctamente mi objeto in_queue ?

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

    Estás sincronizando dos veces, lo cual es inútil y posiblemente ralentiza el código: los cambios al iterar sobre la lista necesitan una sincronización durante toda la operación, lo que estás haciendo con synchronized (in_queue_list) Usar Collections.synchronizedList() es superfluo en ese caso (crea un contenedor que sincroniza las operaciones individuales).

    Sin embargo, dado que está vaciando la lista por completo, la eliminación iterada del primer elemento es la peor manera posible de hacerlo, sice para cada elemento se deben copiar todos los elementos siguientes, haciendo que esto sea una operación O (n ^ 2) – horriblemente lento para listas más grandes.

    En su lugar, simplemente llame a clear() – no se necesita iteración.

    Editar: si necesita la sincronización de un solo método de Collections.synchronizedList() más tarde, esta es la forma correcta:

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

    Pero en muchos casos, la sincronización de un solo método es insuficiente (por ejemplo, para toda iteración, o cuando se obtiene un valor, hacer cálculos basados ​​en él y reemplazarlo con el resultado). En ese caso, debe utilizar la sincronización manual de todos modos, por lo que Collections.synchronizedList() es solo una sobrecarga adicional inútil.

    Mirando tu ejemplo, creo que ArrayBlockingQueue (o sus hermanos) pueden ser de utilidad. Cuidan la sincronización por usted, por lo que los hilos pueden escribir en la cola o peek / take sin trabajo de sincronización adicional de su parte.

    Eso es correcto y documentado:

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

    Sin embargo, para borrar la lista, simplemente llame a List.clear () .

    Sí, es la forma correcta, pero se requiere el locking sincronizado si desea que todas las eliminaciones juntas sean seguras, a menos que la cola esté vacía, no se permitan las eliminaciones. Supongo que solo quieres operaciones de cola y dequeue seguras, por lo que puedes eliminar el bloque sincronizado.

    Sin embargo, hay colas concurrentes muy avanzadas en Java, como ConcurrentLinkedQueue

    Tomemos una lista normal (implementada por la clase ArrayList) y hagámosla sincronizada. Esto se muestra en la clase SynchronizedListExample. Pasamos el método Collections.synchronizedList una nueva ArrayList of Strings. El método devuelve una lista de cadenas sincronizada. // Aquí está la clase 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()); } } } } 

    Tenga en cuenta que al iterar sobre la lista, este acceso aún se realiza utilizando un bloque sincronizado que bloquea el objeto synchronizedList. En general, iterar sobre una colección sincronizada se debe hacer en un bloque sincronizado