2012-04-12 18 views
9

¿Hay alguna razón para usar volátiles y sincronizados juntos en este código?Volátil con sincronizados juntos

public class Helper { 
    private volatile int n; 
    private final Object lock = new Object(); 
    public Helper(int n) { 
    this.n = n; 
    } 

    public void setN(int value) { 
    synchronized (lock) { 
     n = value; 
    } 
    } 
} 

Class Helper debe ser seguro para subprocesos. Tengo este ejemplo del libro "Pautas de concurrencia de Java", pero todavía no está claro: ¿cuál es el motivo para usar volátiles y sincronizados juntos en este ejemplo?

+1

¿Cuál es el libro exacto del que hablas? Recomiendo encarecidamente el libro Java Concurrency in Practice (http://jcip.net/) para aprender la simultaneidad de Java. –

+0

He encontrado este libro aquí (Página 167) http://www.sei.cmu.edu/reports/10tr015.pdf Todo en este libro es bastante claro, excepto en este caso solamente –

+0

Use AtomicInteger. – khachik

Respuesta

7

El propósito de este ejemplo es de señalar que syncronized sin volatile no es suficiente en este caso dado el hecho de que objeto puede ser publicada de forma no segura (es decir, sin volatile en Foo):

Si el ayudante campo en la clase Foo no se declara volátil, el n campo debe declararse volátil para que se establezca una relación de ocurrencia antes-anterior entre la inicialización de ny la escritura de Helper en el campo auxiliar. Esto cumple con la directriz "VNA06-J. No suponga que declarar una referencia de objeto volátil garantiza la visibilidad de sus miembros "en la página 35. Esto solo es necesario cuando no se puede confiar en que la persona que llama (clase Foo) declare volátil al ayudante.

Eso es correcto, pero eligieron un mal ejemplo para demostrarlo, porque volatile sin sincronicización es suficiente en este caso.

0

supongo que el volátil se utiliza porque 'n' se encuentra en el constructor

+0

Sí, pero ¿qué motivo utilizar sincronizado en el método setN? –

+0

¿De verdad? No sé cómo invocar al constructor del mismo objeto desde 2 o más hilos, ¿verdad? – hsestupin

+0

No lo sé también) Mi pregunta era acerca de por qué necesitaba la sincronización en el método setN. Si n variable es volátil, setter puede estar sin sincronización adicional. ¿O no? –

1

No es necesario poner el bloque sincronizado todo el cambio en el valor; desde Java 5 esto se hace "automáticamente" para las variables volátiles. Creo que antes de Java 5, no era necesariamente el caso.