Pregunta

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

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

ArrayList<Record> in_queue = null;

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

Ahora estoy tratando de sincronizarlo. ¿Esto sincroniza correctamente mi objeto in_queue ?

List<Record> in_queue_list = Collections.synchronizedList(in_queue);

synchronized (in_queue_list) {
    while (in_queue_list.size() > 0) {
        in_queue_list.remove(0);
    }
}
¿Fue útil?

Solución

Estás sincronizando dos veces, lo que no tiene sentido y posiblemente ralentiza el código: los cambios al iterar sobre la lista necesitan una sincronización en toda la operación, lo que estás haciendo con sincronizado (in_queue_list) Usando 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 iterativa del primer elemento es la peor forma posible de hacerlo, dado que para cada elemento todos los elementos siguientes deben copiarse, lo que hace que sea un O (n ^ 2) operación: horriblemente lenta para listas más grandes.

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

Editar: Si necesita la sincronización de método único de Collections.synchronizedList () más adelante, esta es la forma correcta:

List<Record> 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 todas las iteraciones, o cuando obtiene un valor, haga cálculos basados ??en él y reemplácelo con el resultado). En ese caso, debe usar la sincronización manual de todos modos, por lo que Collections.synchronizedList () es simplemente una sobrecarga adicional inútil.

Otros consejos

Mirando su ejemplo, creo que ArrayBlockingQueue (o sus hermanos) pueden ser de utilidad. Se ocupan de la sincronización por usted, por lo que los hilos pueden escribir en la cola o mirar / tomar 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 el bloque sincronizado es necesario si desea que todas las eliminaciones juntas sean seguras, a menos que la cola esté vacía, no se permiten eliminaciones. Supongo que solo desea operaciones seguras de espera y de cola, para que pueda 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.     Le pasamos al método Collections.synchronizedList una nueva ArrayList of Strings. El método devuelve una Lista sincronizada de cadenas.     // 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<String> synchronizedList = Collections.synchronizedList(new ArrayList<String>());
        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<String> iterator = synchronizedList.iterator();
            while (iterator.hasNext()) {
                log.info("Synchronized Array List Items: " + iterator.next());
            }
        }    
    }
}

Observe que al iterar sobre la lista, este acceso todavía se realiza utilizando un bloque sincronizado que se bloquea en el objeto synchronizedList. En general, la iteración sobre una colección sincronizada debe hacerse en un bloque sincronizado

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top