2012-06-20 8 views
14

Pregunta simple: ¿el modelo de memoria/sincronización de Java garantiza las escrituras del puntero atómico? Es decir, si tenemos hilos de la competencia:¿El puntero de Java escribe atómico?

String shared; 

thread1() 
{ 
    shared = "a"; 
} 

thread2() 
{ 
    shared = "hello world"; 
} 

comenzó al mismo tiempo, se shared siempre garantiza que sea null, "a" o "hello world"?

+0

Tenga en cuenta que, en general, el objeto al que hace referencia la referencia puede no estar completamente inicializado. La implementación normal de 'String' debería estar bien, aunque la especificación no es buena en este tipo de cosas. También hay pocos preciosos tipos realmente inmutables. Si intentas confiar en este tipo de cosas, probablemente estés haciendo algo mal (aunque esa no es una buena razón para no entender por qué). –

Respuesta

3

Será uno de esos tres valores, sí, pero no está definido. El último en "gana".

No lo pidió, pero para completarlo, NO será "hola wor" o alguna versión parcial de esa cadena.

4

Sí. De section 17.7 of the JLS:

escribe y lee las referencias son siempre atómica, independientemente de si se implementan como valores de 32 bits o 64 bits.

(Eso no significa que siempre verá el valor "último", pero eso es un asunto diferente.)

+0

Como corolario, ¿por qué la especificación de Java exigiría un puntero atómico de 64 bits pero no lo mismo para las escrituras largas? – donnyton

+0

@donnyton, las referencias deben ser atómicas y no conozco ningún lenguaje donde las referencias/punteros no sean atómicas (si están correctamente alineadas). En cuanto a por qué los largos no se especifican para ser atómicos, eso incluirá arquitecturas de 32 bits y las escrituras atómicas pueden ser más caras de lograr, mientras que las referencias en systen de 32 bits son simplemente ... bien de 32 bits de ancho. – bestsss

7

Es atómica.

Sin embargo, en el ejemplo que diste, shared 's valor no se necessarly uno denull, a o hello world. Es posible que, sin una sincronización adecuada, cada subproceso nunca vea el valor establecido por otros subprocesos. Así que thread 1 verá a y thread 2 verá hello world al mismo tiempo.

Edit: Añadido referencias para el último párrafo para su posterior lectura

El JLS explica el orden de operación realizada por diferentes hilos, en Chapter 17 - Threads and Locks. Específicamente, en la sección 17.4.5 Happens-before Order. Además, el bien escrito Java Concurrency in Practice explica todo esto a fondo.

+2

No creo que haya algo así como "al mismo tiempo" en este contexto. Con la sincronización, no ocurrirán al mismo tiempo. Sin sincronización, no existe un concepto bien definido de "tiempo" que se aplique. –

+2

@DavidSchwartz para este asunto, el término "tiempo" se usa porque se usa en cualquier otro lugar de nuestro mundo.Significa que a las 9:00 AM de hoy, 'thread 1' trató' shared' con value 'a' y' thread 2' lo trató como 'hello world'. No creo que sea más simple que eso. – yair

+0

Ese uso de "tiempo" no se puede aplicar a dos elementos no instantáneos que no tienen inicios o paradas bien definidos y que no están sincronizados. Por ejemplo, si desea preguntar si dos personas estaban "preparándose para el trabajo al mismo tiempo", debe tener una definición precisa de cuándo comienza el "prepararse para el trabajo", ya sea presionando el botón de repetición en la alarma. parte de "prepararse para el trabajo" o no. Si eso no está bien definido, el concepto de "prepararse para el trabajo al mismo tiempo" tampoco está bien definido. En este contexto, "¿sucedieron al mismo tiempo?" no tiene una respuesta útil. –

Cuestiones relacionadas