variable thread example java multithreading synchronization web-applications

example - thread java



En Java, ¿necesito declarar mi colección sincronizada si es de solo lectura? (5)

Lleno una colección una sola vez cuando comienza mi aplicación de J2EE. Entonces, varios hilos pueden acceder a él al mismo tiempo, pero solo para leerlo.

Sé que el uso de una colección sincronizada es obligatorio para la escritura en paralelo, pero ¿todavía lo necesito para la lectura paralela?


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

En los mapas hash vinculados por orden de acceso, simplemente consultar el mapa con get es una modificación estructural. El javadoc del mapa hash enlazado.

Si está absolutamente seguro de que no hay cachés, no hay estadísticas de colección, ni optimizaciones, ni cosas divertidas en absoluto, no necesita sincronizar. En ese caso, habría puesto una restricción de tipo en la colección: No declare 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 tomándolo también lejos...).


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.


No es necesario, como se explica en otras respuestas. Si quiere asegurarse de que su colección sea de solo lectura, puede usar:

yourCollection = Collections.unmodifableCollection(yourCollection);

(existe un método similar para List, Set, Map y otros tipos de colección)


Depende de si los hilos que están leyendo su colección se inician antes o después de que la esté llenando. Si se inician antes de que lo complete, no tiene garantías (sin sincronización) de que estos subprocesos verán los valores actualizados.

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

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

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 .


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

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

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 de @WMR answser.

Depende de si los hilos que están leyendo su colección se inician antes o después de que la esté llenando. Si se inician antes de que lo complete, no tiene garantías (sin sincronización) de que estos subprocesos verán los valores actualizados.

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

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

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 .