Pregunta

Lleno una colección una sola vez cuando se inicia mi aplicación web J2EE. Luego, varios hilos pueden acceder al mismo tiempo pero solo para leerlo.

Sé que usar una colección sincronizada es obligatorio para la escritura paralela, pero ¿todavía la necesito para la lectura paralela?

¿Fue útil?

Solución

Normalmente no, porque en este caso no está cambiando el estado interno de la colección. Cuando recorres la colección, se crea una nueva instancia del iterador y el estado de la iteración es por instancia del iterador.


Nota aparte: recuerde que al mantener una colección de solo lectura, solo está evitando modificaciones a la colección en sí. Cada elemento de colección aún es cambiable.

class Test {
    public Test(final int a, final int b) {
        this.a = a;
        this.b = b;
    }

    public int a;
    public int b;
}

public class Main {

    public static void main(String[] args) throws Exception {
        List<Test> values = new ArrayList<Test>(2);
        values.add(new Test(1, 2));
        values.add(new Test(3, 4));

        List<Test> readOnly = Collections.unmodifiableList(values);
        for (Test t : readOnly) {
            t.a = 5;
        }

        for (Test t : values) {
            System.out.println(t.a);
        }
    }

}

Esto produce:

5
5

Consideraciones importantes del contestador @WMR.

  

Depende de si los hilos que están   Se inicia la lectura de tu colección.   Antes o después de que lo estés llenando. Si   se inician antes de que lo llenes,   no tiene garantías (sin   sincronizando), que estos hilos   Alguna vez verá los valores actualizados.

     

La razón de esto es la memoria de Java   Modelo, si quieres saber más lee el   sección " Visibilidad " en este enlace:    http://gee.cs.oswego.edu/dl/cpj/jmm. html

     

E incluso si se inician los hilos   Después de llenar su colección, usted   podría tener que sincronizar porque su   la implementación de la colección podría cambiar   su estado interno incluso en lectura   operaciones (gracias Michael   Bar-Sinaí ,   No conocía tales colecciones   existido).

     

Otra lectura muy interesante en el   tema de concurrencia que cubre   temas como la publicación de objetos,   Visibilidad, etc. con mucho más detalle.   es el libro de Brian Goetz Java   Concurrencia en   Practica .

Otros consejos

Depende de si los subprocesos que leen tu colección se inician antes o después de completarlo. Si se inician antes de llenarlo, no tiene garantías (sin sincronización) de que estos subprocesos verán los valores actualizados.

El motivo de esto es el modelo de memoria Java, si quieres saber más, lee la sección " Visibilidad " en este enlace: http://gee.cs.oswego.edu/dl/ cpj / jmm.html

E incluso si los subprocesos se inician después de llenar su colección, es posible que tenga que sincronizar porque la implementación de la colección podría cambiar su estado interno incluso en las operaciones de lectura (gracias Michael Bar-Sinai , no conocía tales colecciones existía en el estándar JDK).

Otra lectura muy interesante sobre el tema de la concurrencia que cubre temas como la publicación de objetos, la visibilidad, etc. con mucho más detalle es el libro de Brian Goetz Java Concurrency in Practice .

En el caso general, deberías. Esto se debe a que algunas colecciones cambian su estructura interna durante las lecturas. Un LinkedHashMap que usa orden de acceso es un buen ejemplo. Pero no solo tome mi palabra por ella:

  

En los mapas hash vinculados ordenados por el acceso, solo consultar el mapa con get es una modificación estructural    javadoc del mapa de hash vinculado

Si está absolutamente seguro de que no hay cachés, estadísticas de recopilación, optimizaciones ni cosas divertidas, no necesita sincronizar. En ese caso, habría puesto una restricción de tipo en la colección: no declarar la colección como un Mapa (que permitiría LinkedHashMap) sino como HashMap (para los puristas, una subclase final de HashMap, pero eso podría estar tomando demasiado) lejos ...).

No tiene que hacerlo, como se explica en otras respuestas. Si desea asegurarse de que su colección es de solo lectura, puede utilizar:

yourCollection = Collections.unmodifableCollection(yourCollection);

(existe un método similar para Lista, Conjunto, Mapa y otros tipos de colección)

La colección en sí no lo hace, pero tenga en cuenta que si lo que contiene no es inmutable también, esas clases separadas necesitan su propia sincronización.

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