Volátil Vs Estático en java


¿Es correcto decir que static significa una copia del valor para todos los objetos y volatile significa una copia del valor para todos los subprocesos?

De todos modos un valor variable estáticotambién va a ser un valor para todos los hilos, entonces ¿por qué deberíamos ir para volátil?

Author: leppie, 2010-03-11

7 answers

Declarar una variable estática en Java, significa que solo habrá una copia, sin importar cuántos objetos de la clase se creen. La variable será accesible incluso sin Objects creado en absoluto. Sin embargo, los subprocesos pueden tener valores almacenados localmente en caché.

Cuando una variable es volátiles y no static, habrá una variable para cada Object. Por lo tanto, en la superficie parece que no hay diferencia de una variable normal, pero totalmente diferente de estático . Sin embargo, incluso con los campos Object, un subproceso puede almacenar en caché un valor de variable localmente.

Esto significa que si dos subprocesos actualizan una variable del mismo Objeto simultáneamente, y la variable no se declara volátil, podría haber un caso en el que uno de los subprocesos tenga en caché un valor antiguo.

Incluso si accedes a un valor estático a través de múltiples subprocesos, ¡cada subproceso puede tener su copia local en caché! Para evitar esto, puede declarar la variable como estática volatile y esto forzará al hilo a leer cada vez el valor global.

Sin embargo, volátil no es un sustituto de la sincronización adecuada!
Por ejemplo:

private static volatile int counter = 0;

private void concurrentMethodWrong() {
  counter = counter + 5;
  //do something
  counter = counter - 5;
}

Ejecutar concurrentMethodWrong simultáneamente muchas veces puede conducir a un valor final de contador diferente de cero!
Para resolver el problema, debe implementar un bloqueo:

private static final Object counterLock = new Object();

private static volatile int counter = 0;

private void concurrentMethodRight() {
  synchronized (counterLock) {
    counter = counter + 5;
  }
  //do something
  synchronized (counterLock) {
    counter = counter - 5;
  }
}

O utilice el AtomicInteger clase.

 331
Author: stivlo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-09 08:09:40

Diferencia entre Estático y Volátil :

Variable estática: Si dos Subprocesos(supongamos t1 y t2) están accediendo al mismo objeto y actualizando una variable que se declara como estática, significa que t1 y t2 pueden hacer su propia copia local del mismo objeto(incluidas las variables estáticas) en su caché respectiva, por lo que la actualización realizada por t1 a la variable estática en su caché local no se reflejará en la variable estática para la caché t2.

Estático las variables se usan en el contexto de Object donde la actualización realizada por un objeto se reflejaría en todos los demás objetos de la misma clase pero no en el contexto de Thread donde la actualización de un subproceso a la variable estática reflejará los cambios inmediatamente a todos los subprocesos (en su caché local).

Variable volátil: Si dos Subprocesos (supongamos t1 y t2) están accediendo al mismo objeto y actualizando una variable que se declara como volátil, entonces significa que t1 y t2 pueden hacer su propia caché local del Objeto excepto la variable que se declara como volátil. Por lo tanto, la variable volátil tendrá solo una copia principal que se actualizará por diferentes subprocesos y la actualización realizada por un subproceso a la variable volátil se reflejará inmediatamente en el otro Subproceso.

 277
Author: Som,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-25 12:51:41

Además de otras respuestas, me gustaría agregar una imagen para ello(pic hace fácil de entender)

introduzca la descripción de la imagen aquí

static las variables pueden almacenarse en caché para subprocesos individuales. En el entorno multihilo si un subproceso modifica sus datos almacenados en caché, puede que no se refleje para otros subprocesos, ya que tienen una copia de los mismos.

volatile la declaración se asegura de que threads no almacene en caché los datos y solo usa la copia compartida .

Imagen fuente

 21
Author: mrsrinivas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-21 08:47:29

Creo que static y volatile no tienen ninguna relación en absoluto. Le sugiero que lea el tutorial de java para comprender Acceso atómico, y por qué usar acceso atómico, comprender qué es intercalado, encontrará la respuesta.

 5
Author: Amitābha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-30 23:35:17

En términos simples,

  1. Estática : static las variables asociadas con la clase, más que con cualquier objeto. Cada instancia de la clase comparte una variable de clase, que está en una ubicación fija en la memoria

  2. Volatile: Esta palabra clave es aplicable a ambos clase y instancia variables.

Usando volátil variables reduce el riesgo de errores de consistencia de memoria, porque cualquier escritura en una variable volátil establece una relación sucede-antes con lecturas posteriores de esa misma variable. Esto significa que los cambios en una variable volátil siempre son visibles para otros hilos

Echa un vistazo a este artículo de Javin Paul para entender las variables volátiles de una mejor manera.

introduzca la descripción de la imagen aquí

En ausencia de la palabra clave volatile, el valor de la variable en cada la pila del hilo puede ser diferente. Al hacer la variable como volatile, todos los subprocesos obtendrán el mismo valor en su memoria de trabajo y se han evitado los errores de consistencia de la memoria.

Aquí el término variable puede ser variable static (clase) o variable instance (objeto).

Con respecto a su consulta :

De todos modos un valor de variable estática también va a ser un valor para todos los hilos, entonces ¿por qué deberíamos ir para volátil?

Si necesito instance variable en mi aplicación, no puedo usar la variable static. Incluso en el caso de la variable static, la consistencia no está garantizada debido a la caché de subprocesos como se muestra en el diagrama.

El uso de variables volatile reduce el riesgo de errores de consistencia de memoria, porque cualquier escritura en una variable volátil establece una relación sucede-antes con lecturas posteriores de esa misma variable. Esto significa que los cambios en una variable volátil son siempre visibles para otros hilos.

Además, también significa que cuando un hilo lee una variable volátil, no solo ve el último cambio en la variable volátil, sino también los efectos secundarios del código que condujo al cambio => los errores de consistencia de memoria todavía son posibles con variables volátiles. Para evitar efectos secundarios, debe usar variables sincronizadas. Pero hay una mejor solución en java.

Usar el acceso simple a variables atómicas es más eficiente que acceder a estas variables a través de sincronización código

Algunas de las clases del paquete java.util.concurrent proporcionan métodos atómicos que no dependen de la sincronización.

Consulte este artículo control de concurrencia de alto nivel para más detalles.

Especialmente echa un vistazo a Variables atómicas.

Preguntas relacionadas:

Volátil Vs Atómico

Volatile boolean vs AtomicBoolean

Diferencia entre volátil y sincronizado en Java

 4
Author: Ravindra babu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:37

El acceso al valor de variable volátil será directo desde la memoria principal. Debe ser utilizado solamente en el ambiente multi-threading. la variable estática se cargará una vez. Si se utiliza en un entorno de subproceso único, incluso si la copia de la variable se actualizará y no habrá ningún daño al acceder a ella, ya que solo hay un subproceso.

Ahora bien, si se utiliza una variable estática en un entorno de subprocesos múltiples, habrá problemas si se espera el resultado deseado. Como cada hilo tiene su propia copia entonces cualquier incremento o decremento en la variable estática de un hilo puede no reflejarse en otro hilo.

Si uno espera los resultados deseados de la variable estática, entonces use volátil con estática en multi-threading, entonces todo se resolverá.

 0
Author: Aslam anwer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-27 07:15:32

Si declaramos una variable como estática, solo habrá una copia de la variable. Por lo tanto, siempre que diferentes hilos accedan a esa variable, solo habrá un valor final para la variable(ya que solo hay una ubicación de memoria asignada para la variable).

Si una variable se declara como volátil, todos los subprocesos tendrán su propia copia de la variable, pero el valor se toma del principal memory.So, el valor de la variable en todos los hilos será el mismo.

Así que, en ambos casos, el punto principal es que el valor de la variable es el mismo en todos los hilos.

 -1
Author: Jitendra Nalwaya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-20 06:04:22