¿Hay algún caso en el que deba preferir la sincronización 'volátil' a la exclusiva?

Sé que al usar la palabra clave volátil en Java obtenemos algún tipo de sincronización débil (permite actualizaciones de visibilidad pero no proporciona un bloqueo real). ¿Existe alguna situación en la que se deba dar preferencia a la volatilidad sobre el bloqueo real al implementar programas concurrentes? Hay una pregunta algo similar en SO que dice volátil como mecanismo de sincronización pero eso fue etiquetado en C#.

preguntado el 30 de junio de 12 a las 15:06

Esta La respuesta explica por qué la volatilidad no siempre es lo suficientemente buena. Eso se aplica tanto a Java como a C#. -

3 Respuestas

Si el estado compartido consiste en un solo campo y no usa ninguna construcción get-and-set (como i++ por ejemplo) para asignarlo, entonces volátil es lo suficientemente bueno. Sin embargo, la mayoría de los usos volátiles se pueden reemplazar por el uso de tipos AtomicXxx (que proporcionan operaciones atómicas de obtención y configuración).

Respondido el 30 de junio de 12 a las 15:06

En resumen, debería preferir evitar los bloqueos donde no sean necesarios, ya que los bloqueos exponen su programa a interbloqueos y reducen el rendimiento al excluir la concurrencia de partes críticas del código. Entonces, siempre que la situación lo permita, confíe por todos los medios en volatile; si todo lo que necesita adicionalmente son operaciones atómicas de dos pasos como comparar e intercambiar, use AtomicReference. retroceder a synchronized solo para los escenarios donde esta es la única opción. Por ejemplo, si necesita inicializar perezosamente un objeto pesado, necesitará bloqueos para evitar la doble inicialización, pero nuevamente, no para obtener la instancia ya inicializada (modismo de verificación doble).

contestado el 23 de mayo de 17 a las 12:05

OTOH, volátil es una palabra clave que no se comprende bien y, en muchas situaciones, la sincronización no genera una sobrecarga de rendimiento significativa. El uso de API de alto nivel (bloqueo de colas, atómicos, semáforos, colecciones concurrentes, etc.) es, la mayoría de las veces, la técnica mejor y más segura. - JB Nizet

Dicho esto, muchas de las API de alto nivel utilizan volatile internamente. - Luis Wassermann

... y fundamentalmente construir sobre volatile garantías. Javadoc de muchosjava.util.concurrent clase especifica explícitamente su semántica "como si estuviera escribiendo/leyendo un volatile". - Marko Topolnik

@JBNizet, agregaría, lamentablemente no se entiende bien, ya que es un concepto realmente simple. Creo que es solo porque la semántica de Java 1.5 todavía no se ha puesto de moda (y ya lleva cerca de una década). - Marko Topolnik

@seh Gracias por el em-dash, necesito empezar a usarlo... (el en-dash también). - Marko Topolnik

Volatile garantiza que todos los hilos verán la última escritura de una variable por cualquier otro hilo, eso es todo. No hay sincronización involucrada. Si sincroniza el método de lectura y escritura de una variable de instancia, entonces no tiene que hacer que esa variable sea volátil (todos los subprocesos verán la escritura más reciente).

Respondido el 30 de junio de 12 a las 18:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.