2011-08-12 26 views
5

¿Lo mismo para todos los demás objetos atómicos? Es más fácil explicar la pregunta para un AtomicInteger. Dado que más de 1 hilo está accediendo a la referencia a myInt, ¿no es posible que un hilo vea el valor almacenado en caché, por ejemplo nulo, para este objeto, a menos que también se declare volátil? Si no, ¿por qué?¿Es necesario declarar una AtomicReference como volátil?

+0

Intento que todos los campos de AtomicReference sean definitivos. Deberías evitar tener que cambiarlo alguna vez. –

Respuesta

8

No solo no es necesario, sino que es semánticamente incorrecto. AtomicReference contiene la referencia "real" dentro de sí mismo, y gestiona el acceso a ella utilizando sus propias construcciones de sincronización. Las propias construcciones de sincronización de la JVM (synchronized, volatile, etc.) y no se utilizan. El objeto AtomicReference en sí mismo no debe tratarse como volátil. En todo caso, considere hacerlo final.

Considere también this question - volatile puede considerarse una alternativa al uso de AtomicReference, si todo lo que necesita es obtener y configurar operaciones.

+0

¿Por qué no? Un mapa concurrente bien podría ser retenido por un campo volátil por razones legítimas, y no veo por qué esto no debería ser cierto para los objetos "atómicos". –

+0

@Enno: Claro, supongo que podrías inventar un escenario donde sea apropiado. Sin embargo, si vieras 'Volátil AtomicReference' en el código, seguramente no sería lo que el autor pretendía. – skaffman

+0

@skaffman: Claro que AtomicReferance contiene la referencia real al objeto objetivo dentro de sí mismo, pero me refiero a la referencia a este objeto AtomicReference. Pero de hecho puedo hacerlo definitivo, y tiene mucho sentido también. ¡Gracias! –

1

Los objetos "atómicos" no son inmutables, por lo que solo deben protegerse con hilos si se publican correctamente. Por ejemplo, cuando haces algo como esto, necesitarás usar la palabra clave volátil.

volatile AtomicInteger counter = // initialize counter 

int harvest(){ 
    AtomicInteger old = counter; 
    counter = new AtomicInteger(); 
    return old.get(); 
} 

Si elimina el volátil del código anterior, podría perder algunos incrementos. De acuerdo con la especificación, también puede obtener una referencia a un objeto AtomicInteger que no está completamente construido, y así obtener un comportamiento indefinido.

Entonces, ¿necesita declarar su objeto atómico como volátil? La respuesta es, depende. Solo son seguros para subprocesos siempre que se publiquen correctamente, como cualquier otro objeto seguro para subprocesos (excepto objetos inmutables, que son casos especiales). En la mayoría de los casos, debes hacerlos definitivos.

Cuestiones relacionadas