Shared variable old value

When reading Concurrency in practice, I read that

Not. The visibility demonstrates that insufficiently synchronized programs can cause unexpected results: stale data. the read thread checks for readiness, it can see the stale value. If out of sync is used every time a variable is accessed, it is possible to see an obsolete value for that variable. Worse, not all or nothing: a thread can see the date value before one variable but the stale value of another variable that was written in the beginning

public class NoVisibility {
    private static boolean ready;
    private static int number;
    private static class ReaderThread extends Thread {
    public void run() {
    while (!ready)
    Thread.yield();
    System.out.println(number);
    }
    }
    public static void main(String[] args) {
    new ReaderThread().start();
    number = 42;
    ready = true;
    }
    }

      

I don't understand the meaning of the outdated ones. Both threads are using the same reference, how the value changed by one will never or will not be visible to the other thread?

+2


source to share


4 answers


It says that the main intent is to set number = 42 and ready = true at the same time, but since they were called in that particular order, there is a race condition with your ReaderThread where it could (possibly will) print from the number even if we really don't want to.



They would like you to sync these 2 variables that were set together.

+1


source


This is not a Java problem. Processors have caches. Without a sync processor, 1 can read a value into its cache from memory, change it in the cache, but never flush it, then processor 2 reads an obsolete value from memory



+4


source


Each thread has its own stack, so its own copy of the variables can be accessed. When a thread is created, it copies the value of all available variables into its own memory. The volatile keyword is used to tell jvm " Warning, this variable may be changed in another Thread ". Without this keyword, the JVM can optimize, such as never updating those local copies on some threads. Energetic flow force to update the original variable for each variable.

DZone source

Implementation of equipment

This is due to CPU optimization that is done to quickly access variables. When the variable is stored in the cache, it is much faster than accessing the memory every time. So to clear the cache, you need to tell volatile

go and clear the cache and rebuild it as this variable is changing on a different thread.

Variables are cached static

as well, they are also eligible for caching for the same reason as fast access. So yes, you need volatile

for variables static

.

See also:

What does volatile do?

+3


source


This issue is related to a memory visibility

multithreading issue .

If you want to read / get the value of an object that can be changed by multiple threds; then you need to be careful. Let's take an example to highlight the point:

public class XYZ{
   private String state;

   public synchronized setState(..){
      //set state
   } 
   public String getState(){
      return state;
   }

      

}

The above example does not sync the getter method that returns the state. This way you can get stale data (even if its static)

The only way to get the latest data is to either synchronize the get method or declare the state as mutable.

+2


source







All Articles