Cuando das su lista para otro hilo por medio de hilo de seguridad (por ejemplo, utilizando un bloque sincronizado, una variable volátil o un AtomicReference
), se garantiza que el segundo hilo ve toda la lista en el estado que fue cuando se transfiere (o cualquier estado posterior, pero no un estado anterior).
Si no lo cambia después, tampoco necesita su synchronizedList.
Editar (después de algunos comentarios, hacer copias de seguridad de mi reclamo):
asumo la siguiente:
tenemos una variable volátil list
.
volatile List<String> list = null;
Tema A:
- crea una lista L y L se llena con elementos.
- conjuntos
list
para apuntar a L (esto significa escribe L a list
)
- no hace modificaciones adicionales en L.
fuente de la muestra:
public void threadA() {
List<String> L = new ArrayList<String>();
L.add("Hello");
L.add("World");
list = l;
}
Tema B:
- lee K de
list
- itera sobre K, imprimiendo los elementos.
fuente de la muestra:
public void threadB() {
List<String> K = list;
for(String s : K) {
System.out.println(s);
}
}
Todos los otros hilos no tocan la lista.
Ahora tenemos esto:
- las acciones 1-A y 2-A en Hilo A están clasificadas por program order modo 1 está antes 2.
- La acción 1-B y 2 -B en el subproceso B están ordenados por program order así que 1 viene antes 2.
- La acción 2-A en el subproceso A y la acción 1-B en el subproceso están ordenados por synchronization order, por lo que 2-A viene antes de 1-B, desde
Una escritura en una variable volátil (§8.3.1.4) v sincroniza con todas las lecturas subsiguientes de v por cualquier subproceso (donde la subsecuente se define según el orden de sincronización).
El happens-before -order es el cierre transitivo de las órdenes de programa de los hilos individuales y el orden de sincronización. Así tenemos:
1-A-ocurre antes del 2-A-ocurre antes del 1-B-ocurre antes del 2-B
y por lo tanto 1-A-ocurre antes del 2-B.
- Por último,
Si una acción sucede-antes de que otro, entonces la primera es visible desde y pedidas antes de la segunda.
Así que nuestro hilo iteración realmente puede ver toda la lista, y no sólo algunas partes de ella. Por lo tanto, transmitir la lista con una sola variable volátil es suficiente, y no necesitamos sincronización en este caso simple.
Una edición más (en este caso, ya que tengo más libertad que en el formato de los comentarios) sobre el programa de fin de hilo A. (también añadido un código de ejemplo anterior.)
Desde el JLS (sección program order):
Entre todas las acciones entre hilos realizadas por cada t hilo, el orden del programa de T es un orden total que refleja el orden en que estas acciones sería realizado de acuerdo con la semántica intra-hilo de t.
Entonces, ¿qué son la semántica intra-hilo de rosca A?
Algunos paragraphs above:
El modelo de memoria determina qué valores se pueden leer en todos los puntos en el programa. Las acciones de cada hebra en aislamiento deben comportarse como se rigen por la semántica de esa hebra, con la excepción de que los valores que ve cada lectura son determinados por el modelo de memoria. Cuando nos referimos a esto, decimos que el programa obedece a semántica intrahilo. La semántica intrahilo es la semántica de los programas de un solo subproceso , y permite la predicción completa del comportamiento de un subproceso basado en los valores observados por las acciones de lectura dentro del subproceso. Para determinar si las acciones de thread t en una ejecución son legales, simplemente evaluamos la implementación de thread t, ya que se realizaría en un único contexto de subprocesamiento, como se define en el resto de esta especificación.
El resto de esta especificación incluye section 14.2 (Blocks):
Un bloque se ejecuta mediante la ejecución de cada una de la declaración de variable local declaraciones y otras declaraciones en orden desde el primero al último (de izquierda a derecha) .
Por lo tanto, el orden del programa es de hecho el orden en que las declaraciones/expresiones se dan en el código fuente del programa.
Por lo tanto, en nuestra fuente de ejemplo, las acciones de memoria crear un nuevo ArrayList, complemento "Hola", añadir "Mundial" y asignan a list
(los tres primeros consisten en más subacciones) de hecho están en esta orden de programa.
(La máquina virtual no tiene que ejecutar las acciones en este orden, pero esta orden del programa sigue contribuyendo a la sucede antes orden, y por lo tanto a la visibilidad a otros hilos.)
¿Tiene usted intenté envolver tu lista en una lista sincronizada y resultó ser demasiado lenta? – biziclop
"nihilistic"? .. – DJClayworth