Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stale value of Shared variable

While reading Concurrency in practice I read that:

NoVisibility demonstrated one of the ways that insufficiently synchronized programs can cause surprising results: stale data. When the reader thread examines ready, it may see an out of date value. Unless synchronization is used every time a variable is accessed, it is possible to see a stale value for that variable. Worse, staleness is not all or nothing: a thread can see an up-to-date value of one variable but a stale value of another variable that was written first.

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 am not getting meaning of stale. Both threads are sharing the same reference, how can a value modified by one be or not be visible to other thread?

like image 449
KCS Avatar asked Dec 01 '22 02:12

KCS


2 Answers

Each thread has its own stack, and so its own copy of variables it can access. When the thread is created, it copies the value of all accessible variables in its own memory. The volatile keyword is used to say to the jvm "Warning, this variable may be modified in an other Thread". Without this keyword the JVM is free to make some optimizations, like never refreshing those local copies in some threads. The volatile force the thread to update the original variable for each variable.

Source DZone

Hardware Implementation

This happens due to the processor optimizations that are done for fast access of variables. When the variable is kept in the cache then it is much faster to access than going to memory everytime. So for flushing the cache you need to say volatile go and flush the cache and rebuild it as this variable is being modified in other thread.

The caching of static variables is also done, they too are a eligible for caching due to same reason fast access. So yes you need volatile for static variables too.

See also:

What does volatile do?

like image 111
Narendra Pathai Avatar answered Dec 05 '22 12:12

Narendra Pathai


It's not Java specific issue. Processors have caches. Without synchronization processor 1 can read a value into its cache from memory, modify it in its cache but never flush it, then processor 2 reads stale value from memory

like image 33
Evgeniy Dorofeev Avatar answered Dec 05 '22 13:12

Evgeniy Dorofeev