4

I've looked at this answer, and it states how:

Under the new memory model, when thread A writes to a volatile variable V, and thread B reads from V, any variable values that were visible to A at the time that V was written are guaranteed now to be visible to B.

Therefore, given the example:

public class Main {
    static int value = -1;
    static volatile boolean read;

    public static void main(String[] args) {
        Thread a = new Thread(() -> {
            value = 1;
            read = true;
        });

        Thread b = new Thread(() -> {
            while (!read);

            System.out.println("Value: " + value);
        });

        a.start();
        b.start();
    }
}

Is the change to value (from -1 to 1) guaranteed to be visible to thread b despite the non-volatility of value (only read)?

If so, given a bunch of changes that are performed with the intention of being visible to another thread, is there any purpose in making any variable changed other than the last one volatile?

Kartik
  • 7,677
  • 4
  • 28
  • 50
Mario Ishac
  • 5,060
  • 3
  • 21
  • 52

1 Answers1

5

Yes, the change to value is guaranteed to be visible to thread b.

JLS 17.4.4. Synchronization Order says:

  • A write to a volatile variable v (§8.3.1.4) synchronizes-with all subsequent reads of v by any thread (where "subsequent" is defined according to the synchronization order).

JLS 17.4.5. Happens-before Order says:

Two actions can be ordered by a happens-before relationship. If one action happens-before another, then the first is visible to and ordered before the second.

If we have two actions x and y, we write hb(x, y) to indicate that x happens-before y.

  • If x and y are actions of the same thread and x comes before y in program order, then hb(x, y).

  • There is a happens-before edge from the end of a constructor of an object to the start of a finalizer (§12.6) for that object.

  • If an action x synchronizes-with a following action y, then we also have hb(x, y).

  • If hb(x, y) and hb(y, z), then hb(x, z).

Bullet 1 says that value = 1 happens-before read = true.
Bullet 3 says that read = true happens-before !read.
Bullet 1 says that !read happens-before "Value: " + value.
Bullet 4 says that value = 1 happens-before "Value: " + value.

Community
  • 1
  • 1
Andreas
  • 154,647
  • 11
  • 152
  • 247
  • Okay, with these rules in mind, could you cover the second question as well (regarding use of making variables not changed last volatile)? – Mario Ishac Sep 26 '18 at 04:08
  • 3
    @TheeNinjaDev Do you want us to speculate if there can be some scenario where making more than one of them `volatile` would be needed? --- You already have an answer here: If the last one changed is always the first one read by the other thread, then there is no need to make the others volatile. If you can't make that guarantee, the answer is: It depends! – Andreas Sep 26 '18 at 04:16