I read (p 378) ( I apologize for the great extract from the source ):

The volatile access volatile tells the compiler that a variable that it modifies may be unexpectedly changed in other parts of the program. One of these situations occurs in multi-threaded programs, where sometimes two or more execution threads have shared access to the same variable. For efficiency reasons, each stream may have its own private copy of this variable. A real (or main) copy of a variable is updated at different times, for example, upon entering a synchronized method. This approach is quite workable, but not always sufficiently effective. Sometimes it is required that a master copy of a variable always reflects its current state. And for this it is enough to declare a variable as volatile , thereby telling the compiler to always use the main copy of this variable (or at least maintain any closed copies of it that are updated by the main copy, and vice versa). In addition, access to the master copy of a variable must be done in the same manner as to any closed copy.

Question:

Each stream can store its own copy of the variable. How is the " master copy of a variable " defined in a multithreaded program? What is the main stream? Access volatile defines? But after all, all threads see this variable in the same way.

    1 answer 1

    How is the " master copy of a variable " defined in a multithreaded program?

    The main copy of a variable here means the variable whose value is relevant at the moment.

    What is the main stream?

    If a variable is declared as volatile , then in any stream it will be the main one, otherwise you can expect any other behavior (somewhere it will be the main one, and somewhere not).

    But after all, all threads see this variable in the same way.

    If a variable is declared as volatile , then all streams will see this variable in the same way, otherwise streams can cache this variable and, in this case, other streams will not see the current value of this variable.

    The volatile keyword guarantees the visibility of a variable . That is, a variable declared with such a modifier at any time in any stream will be of current importance.

    I will give a small example:

     public class Main { public static void main(String[] args) { Foo foo = new Foo(); Thread checkThread = new Thread(new Runnable() { @Override public void run() { foo.checkValue(); } }); checkThread.setName("Check Thread"); checkThread.start(); Thread incThread = new Thread(new Runnable() { @Override public void run() { foo.incValue(); } }); incThread.setName("Inc Thread"); incThread.start(); } private static class Foo { private volatile int mValue; public Foo() { mValue = 1; } public void checkValue() { int localValue = mValue; while (localValue < 5) { if (localValue != mValue) { System.out.println(Thread.currentThread().getName() + ": value = " + mValue); localValue = mValue; } } } public void incValue() { for (int i=0; i<4; i++) { System.out.println(Thread.currentThread().getName() + ": value = " + mValue); mValue++; try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } } } } 

    The checkThread copies the value of mValue to the local variable localValue and localValue in a loop until localValue < 5 . In this case, the condition localValue != mValue checked in the loop, if it is true (this means changing the variable mValue ), then the local variable localValue assigned the current value mValue .

    The incThread increments the incThread variable with a mValue 500 milliseconds until its value reaches 5.

    If the mValue variable mValue declared as volatile , then you will always get a strictly console output:

     Inc Thread: value = 1 Check Thread: value = 2 Inc Thread: value = 2 Check Thread: value = 3 Inc Thread: value = 3 Check Thread: value = 4 Inc Thread: value = 4 Check Thread: value = 5 

    If the mValue variable mValue NOT declared as volatile , then you cannot guarantee that the console output will always be the same as in the previous case. It may be the same, and maybe another, for example:

     Inc Thread: value = 1 Inc Thread: value = 2 Inc Thread: value = 3 Inc Thread: value = 4 

    or this:

     Inc Thread: value = 1 Check Thread: value = 2 Inc Thread: value = 2 Inc Thread: value = 3 Inc Thread: value = 4 

    In the case when the variable is declared as volatile , after it is incremented in the Inc Thread , the Check Thread immediately sees this change.

    In the case when the variable is NOT declared as volatile , in the first output to the console, you can see that Check Thread did not see the change of this variable at all, and in the second case it saw only the first increment.