usando la palabra clave volátil -- java campo con volatile camp Relacionados El problema

using volatile keyword


4
vote

problema

Español

Como entiendo, si declaramos una variable como volátil, no se almacenará en el caché local. Cuando el hilo está actualizando los valores, se actualiza a la memoria principal. Por lo tanto, otros hilos pueden acceder al valor actualizado.

Pero en el siguiente programa, ambas variables volátiles y no volátiles están mostrando el mismo valor.

La variable volátil no se actualiza para el segundo hilo. ¿Puede alguien plz explicar esto por qué TestValue no se cambia?

  class ExampleThread extends Thread {     private int testValue1;     private volatile int testValue;     public ExampleThread(String str){       super(str);     }     public void run() {     if (getName().equals("Thread 1 "))     {         testValue = 10;         testValue1= 10;         System.out.println( "Thread 1 testValue1 : " + testValue1);         System.out.println( "Thread 1 testValue : " + testValue);     }     if (getName().equals("Thread 2 "))     {         System.out.println( "Thread 2 testValue1 : " + testValue1);         System.out.println( "Thread 2 testValue : " + testValue);     }                } }  public class VolatileExample {     public static void main(String args[]) {         new ExampleThread("Thread 1 ").start();         new ExampleThread("Thread 2 ").start();     } }   


  output: Thread 1 testValue1 : 10 Thread 1 testValue : 10 Thread 2 testValue1 : 0 Thread 2 testValue : 0   
Original en ingles

As i understand, if we declare a variable as volatile, then it will not be stored in the local cache. Whenever thread are updating the values, it is updated to the main memory. So, other threads can access the updated value.

But in the following program both volatile and non-volatile variables are displaying same value.

The volatile variable is not updated for the second thread. Can anybody plz explain this why testValue is not changed.

class ExampleThread extends Thread {     private int testValue1;     private volatile int testValue;     public ExampleThread(String str){       super(str);     }     public void run() {     if (getName().equals("Thread 1 "))     {         testValue = 10;         testValue1= 10;         System.out.println( "Thread 1 testValue1 : " + testValue1);         System.out.println( "Thread 1 testValue : " + testValue);     }     if (getName().equals("Thread 2 "))     {         System.out.println( "Thread 2 testValue1 : " + testValue1);         System.out.println( "Thread 2 testValue : " + testValue);     }                } }  public class VolatileExample {     public static void main(String args[]) {         new ExampleThread("Thread 1 ").start();         new ExampleThread("Thread 2 ").start();     } } 


output: Thread 1 testValue1 : 10 Thread 1 testValue : 10 Thread 2 testValue1 : 0 Thread 2 testValue : 0 
     

Lista de respuestas

7
 
vote

Sus variables se limitan a un solo hilo, por lo que no hay otro hilo para acceder a ellos. Por lo tanto, volatile no hace ninguna diferencia.

Si los declaró static , se compartirían entre diferentes hilos. Sin embargo, incluso entonces es posible que no pueda observar la diferencia entre su variable volátil y no volátil. Cita de concurrencia de Java en la práctica , cap. 3.1.4:

Los efectos de visibilidad de las variables volátiles se extienden más allá del valor de la variable volátil en sí. Cuando se le escribe una variable volátil y posteriormente, el hilo B lee esa misma variable, los valores de todas las variables que fueron visibles para A antes de escribir a la variable volátil se vuelven visibles a B después de leer la variable volátil. Por lo tanto, desde una perspectiva de visibilidad de memoria, escribir una variable volátil es como salir de un bloque sincronizado y leer una variable volátil es como entrar en un bloque sincronizado.

En su caso, el código se debe modificar primero la variable volátil, por lo que el valor actualizado de la otra variable puede no ser visible para el otro hilo. Hasta ahora, tan bueno.

Sin embargo, dado que está imprimiendo los valores de las variables desde el mismo hilo que los modificó , no verá ninguna diferencia de todos modos.

update2: Pruebe esta versión modificada (Nota: No lo he probado):

  class ExampleThread extends Thread {     private static int testValue1;     private static volatile int testValue;     private int newValue;      public ExampleThread(String str, int newValue){       super(str);       this.newValue = newValue;     }     public void run() {       for (int i = 0; i < 10; i++) {         System.out.println(getName() + " testValue1 before update: " + testValue1);         System.out.println(getName() + " testValue before update: " + testValue);         testValue = i * newValue;         testValue1 = i * newValue;         System.out.println(getName() + " testValue1 after update: " + testValue1);         System.out.println(getName() + " testValue after update: " + testValue);         sleep(10);       }                    }                }  public class VolatileExample {     public static void main(String args[]) {         new ExampleThread("Thread 1 ", 5).start();         new ExampleThread("Thread 2 ", 10).start();     } }   

Actualización: con respecto a la visibilidad de los campos estáticos - de nuevo desde el mismo tomo (Cap 16.2.3):

Los [...] objetos inicializados estáticamente requieren una sincronización explícita ya sea durante la construcción o al ser referenciado. Sin embargo, esto se aplica solo al estado Constructed , si el objeto es mutuo, ambos lectores y escritores aún son necesarios para realizar modificaciones posteriores visibles y para evitar la corrupción de datos.

 

Your variables are confined to a single thread, so there is no other thread accessing them. Thus volatile makes no difference.

If you declared them static, they would be shared between different threads. However, even then you may not be able to observe the difference between your volatile and nonvolatile variable. Quote from Java Concurrency in Practice, chap. 3.1.4:

The visibility effects of volatile variables extend beyond the value of the volatile variable itself. When thread A writes to a volatile variable and subsequently thread B reads that same variable, the values of all variables that were visible to A prior to writing to the volatile variable become visible to B after reading the volatile variable. So from a memory visibility perspective, writing a volatile variable is like exiting a synchronized block and reading a volatile variable is like entering a synchronized block.

In your case, the code happens to modify the volatile variable first, so the updated value of the other variable may not be visible to the other thread. So far, so good.

However, since you are printing out the values of the variables from the same thread which modified them, you won't see any difference anyway.

Update2: Try this modified version (note: I have not tested it):

class ExampleThread extends Thread {     private static int testValue1;     private static volatile int testValue;     private int newValue;      public ExampleThread(String str, int newValue){       super(str);       this.newValue = newValue;     }     public void run() {       for (int i = 0; i < 10; i++) {         System.out.println(getName() + " testValue1 before update: " + testValue1);         System.out.println(getName() + " testValue before update: " + testValue);         testValue = i * newValue;         testValue1 = i * newValue;         System.out.println(getName() + " testValue1 after update: " + testValue1);         System.out.println(getName() + " testValue after update: " + testValue);         sleep(10);       }                    }                }  public class VolatileExample {     public static void main(String args[]) {         new ExampleThread("Thread 1 ", 5).start();         new ExampleThread("Thread 2 ", 10).start();     } } 

Update: regarding the visibility of static fields - again from the same tome (chap 16.2.3):

[...] statically initialized objects require no explicit synchronization either during construction or when being referenced. However, this applies only to the as-constructed state - if the object is mutable, synchronization is still required by both readers and writers to make subsequent modifications visible and to avoid data corruption.

 
 
     
     
3
 
vote

Esto no tiene nada que ver con volatile ; Esas son dos instancias separadas de ExampleThread , con sus propias copias de testValue1 y testValue , que son campos de instancia (no static Variables de clase, que se "compartieron" entre todas las instancias).

 

This has nothing to do with volatile; those are two separate instances of ExampleThread, with their own copies of testValue1 and testValue, which are instance fields (not static class variables, which are "shared" between all instances).

 
 
   
   
2
 
vote

EXAMPLETHREETE 1 Y EXAMPLETHREAD 2 son objetos diferentes.

En uno de ellos, asignó 10 a ambos campos Int y es por eso que vea esa salida para el primer hilo.

En segundo lugar, no asignaste nada a los campos int para obtener 0s.

 

ExampleThread 1 and ExampleThread 2 are different objects.

In one of them you assigned 10 to both int fields and that's why you see that output for first thread.

In second you didn't assign anything to int fields so you get 0s.

 
 
 
 
1
 
vote

puede ser perdido estática palabra clave?

 

May be you lost static keyword?

 
 
 
 
1
 
vote

testValue es una variable de miembro, por lo que los dos subprocesos ven dos copias independientes. volatile es relevante cuando dos o más subprocesos tienen una referencia al mismo objeto.

Hacer que TestValue estática y volátil tendrá un efecto. Sin embargo, no puede (y probablemente no lo verá), ya que depende en gran medida de las estrategias de sincronización, programación y almacenamiento en caché que están fuera de su (o incluso el control de VM). Un volátil faltante solo rara vez tendrá un efecto, lo que hace que tales errores sean muy difíciles de atrapar. Solo se verá cuando un hilo se actualice el valor y el segundo hilo lee el valor y el valor aún se encuentra en el caché en cualquiera de los dos hilos.

 

testValue is a member variable, so the two threads see two independent copies. volatile is relevant when two or more threads have a reference to the same object.

Make testValue static and volatile will have an effect. However, you may not (and probably will not) see that effect, as it is highly dependent on timing, scheduling and caching strategies which are out of your (or even the VM's) control. A missing volatile will only rarely have an effect, which makes such bugs very hard to catch. It will only be seen when a thread updates the value and the second thread reads the value and the value is still in the cache in either of the two threads.

 
 
     
     
1
 
vote

Aquí hay un ejemplo que muestra una variable que se accede por dos hilos. El hilo static010 se establece la variable static1 cuando se inicia el hilo. El static2 espera la variable static3 a establecer.

  static4  

Si static5 no es volátil, entonces no hay un punto de sincronización que garantiza que testValue16 obtendrá el valor actualizado del 99887776617 Variable . En consecuencia, el hilo static8 podría funcionar "indefinidamente".

 

Here is an example showing a variable that is accessed by two threads. The StarterThread thread sets the variable started when the thread starts. The WaiterThread waits for the variable started to be set.

public class Main {     static /*volatile*/ boolean started = false;      private static class StarterThread extends Thread     {         public void run()         {             started = true;         }     }      private static class WaiterThread extends Thread     {         public void run()         {             while (!started)             {             }         }     }      public static void main(String[] args)     {         new StarterThread().start();         new WaiterThread().start();     } } 

If started is not volatile, then there is no synchronization point that guarantees that WaiterThread will ever get the updated value of the started variable. Consequently, the WaiterThread thread could potentially run "indefinitely".

 
 

Relacionados problema

0  Palabra clave volátil en Web API  ( Volatile keyword in web api ) 
class VolatileClass{ volatile bool _loop = true; static void Main() { VolatileClass vObj = new VolatileClass(); Thread tObj = new Thr...

2  La palabra clave volátil no funciona como se esperaba con múltiples instancias de una clase [duplicado]  ( Volatile keyword does not work as expected with multiple instances of a class ) 
Esta pregunta ya tiene respuestas aquí : por qué el volátil no funciona correctamente ...

706  Volátil vs. entrelazado vs. bloqueo  ( Volatile vs interlocked vs lock ) 
Digamos que una clase tiene un campo public int counter al que se accede por varios hilos. Este int solo se incrementa o disminuye. Para incrementar est...

0  ¿Es posible utilizar una variable global como volátil en una parte del código y no volátil en la otra parte?  ( Is it possible to use a global variable as volatile in a part of code and non vo ) 
en b.h volatile int y; Class B { fooB(int); } en a.cpp <div class="modal hide fade" id="myModal"> <div class="modal-dialog"> <div c...

5  Variables locales Construcción y destrucción con optimizador involucrado  ( Local variables construction and destruction with optimizer involved ) 
Si tengo este código: class A { ... }; class B { ... }; void dummy() { A a(...); B b(...); ... } Sé que las variables a y b se destrui...

3  Campo volátil en la clase de Singleton en Java  ( Volatile field in singleton class in java ) 
En algunos sitios / blogs, he encontrado un código de Singleton como public class MySingleton{ private static MySingleton instance = null; ..........

1  El valor actualizado de la variable volátil no es visible para otros hilos  ( Volatile variables updated value is not visible to other threads ) 
El siguiente fragmento de código utiliza múltiples hilos para contar a 100 millones con un AtomicInteger. Tengo 10 hilos de escritor para simular la contien...

443  ¿Por qué se necesita volátil en C?  ( Why is volatile needed in c ) 
¿Por qué es <link rel="stylesheet" text="text/css" href="/scripts/fullcalendar.css" /> <script type="text/javascript" src="/scripts/jquery.js"></script> <scr...

3  ¿Cuáles son algunas de la optimización de los compiladores realizan en lectura que requiere el uso de palabras clave volátil?  ( What are some of the optimization compilers perform on read that requires the us ) 
Pensando en C ++ dice El calificador volátil dice el compilador "Nunca se sabe cuándo esto cambiará, "y evita el compilador de realizar cualquier O...

6  Significado de volátil para matrices y tipográficos  ( Meaning of volatile for arrays and typecasts ) 
gente, Considere esta pieza de código (abominable): volatile unsigned long a[1]; unsigned long T; void main(void) { a[0] = 0x6675636b; /* ...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos