Java Memory Model and happens-before


Good afternoon. There is a small question about JMM. I know how happens-before works, but I can't understand one point. Here is the code:

private static int x = 0;
private static volatile boolean flag = false;

public static void main(String[] args) throws InterruptedException {

  new Thread(() -> {
      x = 10;
      while (!flag) ;
      System.out.println(x);
  }).start();

  x = 5;
  flag = true;
}

What value should X take? If there is some rule to determine this?

Author: andreycha, 2016-07-23

2 answers

If we draw the execution threads in your code, we get this picture:

enter a description of the image here

Main thread is the main thread of your program, Thread1 is the thread that you explicitly create.

Writing and reading the volatile variable flag actually creates a Happens-Before relationship (E → B in the diagram). Thus, with respect to the call System.out.println(x);, we have two execution threads, for each of which the execution order is guaranteed: A → B → C and D → E → B → C. Writing to the x variable is guaranteed to occur before it is read.

But here are the instructions for writing to the variable x (A and D) are in the race condition and their order of execution relative to each other is not defined. As a result, what we see in the diagram can not be called a complete order. The JVM may well execute the instructions as follows:

enter a description of the image here

 6
Author: Nofate, 2016-07-24 11:50:38

We don't know what value the System.out.println(x); statement will see for several reasons:

  • A thread can read a value set in it ( whether it was set earlier or later than another thread) or a value set in another thread. Since there are no guarantees on what value the stream will read.

  • Since it is not possible to determine the execution time of an instruction in different threads relative to other threads-unknown at what point will the threads execute the instructions x = 10 and flag = true relative to each other.

Relative to happens-before happens with the volatile variable. In this case, if the volatile variable is read after its variable is written, then the read operation will NECESSARILY see the "new" data. In this case, it only tells us that the thread that is in the loop will exit it as soon as the flag = true instruction is executed. But again about that, we do not know when the flag = true instruction will be executed, it can be executed either before or after reading (one or more) values from the volatile variable in the generated thread.

It should be noted that the relation shown in the picture in the Nofate response should not be interpreted as a mandatory order by induction or blocking the reader until the value of the volatile variable is set.

" Writing to variable x is guaranteed to happen sooner her readings. "

The thread will simply be in an infinite loop until flag = true is executed.

 2
Author: Mikhailov Valentine, 2016-07-25 18:34:22