¿Es correcto decir que static
significa una copia del valor para todos los objetos y volatile
una copia del valor para todos los hilos?
De todos modos, un static
valor variable también será un valor para todos los hilos, entonces, ¿por qué deberíamos elegir volatile
?
Respuestas:
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 ninguna
Objects
creación. Sin embargo, los subprocesos pueden tener valores almacenados en caché localmente.Cuando una variable es volátil y no estática , habrá una variable para cada una
Object
. Entonces, en la superficie parece que no hay diferencia con respecto a una variable normal, pero es totalmente diferente de la estática . Sin embargo, incluso conObject
campos, un subproceso puede almacenar en caché un valor variable localmente.Esto significa que si dos subprocesos actualizan una variable del mismo Objeto al mismo tiempo, y la variable no se declara volátil, podría haber un caso en el que uno de los subprocesos tenga en la memoria caché un valor antiguo.
Incluso si accede a un valor estático a través de múltiples hilos, ¡cada hilo puede tener su copia local en caché! Para evitar esto, puede declarar la variable como estática volátil y esto obligará al hilo a leer cada vez que el valor global.
Sin embargo, ¡ volátil no es un sustituto de la sincronización adecuada!
Por ejemplo:
¡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:
O usa la
AtomicInteger
clase.fuente
Diferencia entre estática y volátil:
Variable estática : Si dos hilos (supongamos
t1
et2
) acceden al mismo objeto y la actualización de una variable que se declara como estática y entonces significat1
yt2
puede hacer su propia copia local del mismo objeto (incluyendo las variables estáticas) en sus respectivos caché, por lo que la actualización hecho port1
la variable estática en su caché local no se reflejará en la variable estática parat2
caché.Las variables estáticas 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 thread a la variable estática reflejará los cambios inmediatamente a todos los subprocesos (en su caché local).
Variables volátiles : Si dos hilos (supongamos
t1
et2
) acceden al mismo objeto y la actualización de una variable que se declara tan volátil, entonces significat1
yt2
puede hacer su propia caché local del objeto , excepto la variable que se declara como una volátil . Por lo tanto, la variable volátil tendrá solo una copia principal que será actualizada por diferentes hilos y la actualización realizada por un hilo a la variable volátil se reflejará inmediatamente en el otro hilo.fuente
volatile
variable se puede compartir entre distintos cachés de CPU. Esto no presenta ningún problema porque la caché negocia la propiedad exclusiva de la línea de caché antes de modificarla.Además de otras respuestas, me gustaría agregarle una imagen (la foto hace que sea fácil de entender)
static
Las variables pueden almacenarse en caché para subprocesos individuales. En un entorno de subprocesos múltiples, si un subproceso modifica sus datos en caché, es posible que no se reflejen para otros subprocesos, ya que tienen una copia de él.volatile
La declaración garantiza que los subprocesos no almacenarán en caché los datos y utiliza solo la copia compartida .fuente de imagen
fuente
Pienso
static
yvolatile
no tengo ninguna relación en absoluto. Le sugiero que lea el tutorial de Java para comprender el acceso atómico , y por qué usar el acceso atómico, comprender lo que está entrelazado , encontrará la respuesta.fuente
En lenguaje sencillo,
estática : las
static
variables están asociadas con la clase , en lugar de con cualquier objeto . Cada instancia de la clase comparte una variable de clase, que está en una ubicación fija en la memoriavolátil : esta palabra clave es aplicable tanto a las variables de clase como de instancia .
Echar un vistazo a este artículo por
Javin Paul
entender las variables volátiles de una mejor manera.En ausencia de
volatile
palabra clave, el valor de la variable en la pila de cada subproceso puede ser diferente. Al hacer la variable comovolatile
, todos los hilos obtendrán el mismo valor en su memoria de trabajo y se evitarán los errores de consistencia de la memoria.Aquí el término
variable
puede serstatic
variable (clase) o variableinstance
(objeto).Con respecto a su consulta:
Si necesito
instance
variable en mi aplicación, no puedo usarstatic
variable. Incluso en caso destatic
variable, no se garantiza la coherencia debido a la memoria caché de subprocesos como se muestra en el diagrama.El uso de
volatile
variables reduce el riesgo de errores de consistencia de la memoria, porque cualquier escritura en una variable volátil establece una relación de suceder antes con lecturas posteriores de esa misma variable. Esto significa que los cambios en una variable volátil siempre son visibles para otros subprocesos.El uso del acceso simple a la variable atómica es más eficiente que acceder a estas variables a través del código sincronizado
Algunas de las clases en el
java.util.concurrent
paquete proporcionan métodos atómicos que no dependen de la sincronización.Consulte este artículo de control de concurrencia de alto nivel para obtener más detalles.
Especialmente eche un vistazo a las variables atómicas .
Preguntas SE relacionadas:
Volátil Vs Atómico
Boolean volátil vs AtomicBoolean
Diferencia entre volátil y sincronizado en Java
fuente
volatile
antes, pero esta respuesta me aclara mucho por qué todavía necesito usarvolatile
lastatic
variable.El acceso a valores variables volátiles será directo desde la memoria principal. Debe usarse solo en entornos de subprocesos múltiples. La variable estática se cargará una vez. Si se usa en un entorno de subproceso único, incluso si la copia de la variable se actualizará y no habrá ningún daño al acceder, ya que solo hay un subproceso.
Ahora, si se usa una variable estática en un entorno de subprocesos múltiples, habrá problemas si se espera el resultado deseado. Como cada subproceso tiene su propia copia, cualquier incremento o disminución en la variable estática de un subproceso puede no reflejarse en otro subproceso.
Si uno espera los resultados deseados de la variable estática, use volátil con estática en subprocesos múltiples y todo se resolverá.
fuente
No estoy seguro de que las variables estáticas se almacenen en caché en la memoria local de subprocesos o NO. Pero cuando ejecuté dos subprocesos (T1, T2) accediendo al mismo objeto (obj) y cuando la actualización realizada por el subproceso T1 a la variable estática se reflejó en T2.
fuente
Si declaramos una variable como estática, solo habrá una copia de la variable. Entonces, cada vez 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 tomará de la memoria principal, por lo que el valor de la variable en todos los subprocesos será el mismo.
Entonces, en ambos casos, el punto principal es que el valor de la variable es el mismo en todos los hilos.
fuente