2008-09-30 10 views

Respuesta

19

Normalmente no, porque usted 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.


Aparte nota: Recuerde que al mantener una colección de sólo lectura que están impidiendo única modificación a la propia colección. 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); 
     } 
    } 

} 

Este salidas:

5 
5 

consideraciones importantes a partir answser @WMR.

Depende de si los hilos que son lectura de su colección se inician antes o después de que haya llenarlo. Si que están comenzaron antes de llenarlo, tiene ninguna garantía (sin de sincronización), que estos hilos van a ver los valores actualizados.

La razón de esto es la modelo de memoria de Java, si usted quiere saber más, lea la sección "visibilidad" en el siguiente enlace: http://gee.cs.oswego.edu/dl/cpj/jmm.html

E incluso si se ponen en marcha los hilos después de completar su colección , que que tenga que sincronizar debido a que su aplicación colección podría cambiar su estado interno leer incluso en operaciones (gracias Michael Bar-Sinai, no sabía que existían esas colecciones ).

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

+0

Esta respuesta no es incorrecta, pero tampoco es suficiente. La respuesta de @WMR tiene algunas advertencias adicionales importantes. En particular, debe considerar la cuestión de asegurarse de que los hilos del lector realmente verán los valores escritos al inicio, ya sea mediante publicación segura o alguna barrera de memoria –

+0

Ver @ WMR y mis respuestas a continuación ... esta respuesta es incorrecta, como obtener() las acciones podrían transformar el estado interno en las colecciones (p. ej., cachés, últimas estadísticas tocadas, etc.). –

+0

@Alex Miller: Creo que la respuesta no solo no es suficiente, claramente dice "No" sin enumerar ninguna condición para este no. Y esto está mal (y como probablemente sepa que es peligroso si confía en él). – WMR

0

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

+0

Guau, gracias. Buen trabajo – mattlant

3

Usted no tiene que, como se ha explicado en otras respuestas.Si desea asegurarse de que su colección es de sólo lectura, puede utilizar:

yourCollection = Collections.unmodifableCollection(yourCollection); 

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

10

Depende de si los hilos que están la lectura de su colección se inicia 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 usted 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 iniciaron después de que complete su colección, puede que tenga para sincronizar porque su implementación de colección podría cambiar su estado interno incluso en operaciones de lectura (gracias Michael Bar-Sinai, no sabía que tales colecciones existieran en el JDK estándar).

Otra lectura muy interesante sobre 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 Concurrency in Practice.

+0

Gracias por esta respuesta, pero ¿se puede usar la ayuda "volátil" para obtener los últimos valores en otros hilos? – SlowAndSteady

9

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 tome mi palabra para ella:

En los mapas de hash vinculados acceso ordenado, simplemente consultando el mapa con GET es una modificación estructural The Linked hash map's javadoc

Si está absolutamente seguro de que hay no hay cachés, no hay estadísticas de colección, no hay optimizaciones, nada de cosas divertidas, no necesitas 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...).

+0

Interesante ... nunca supe que algunas colecciones cambian su estructura interna durante las lecturas. – Jimmy

Cuestiones relacionadas