Question

I have read following article from SO

Difference between synchronization of field reads and volatile

here questioner writes

the point of the synchronization is to ensure that the value of acct.balance that are read by this thread is current and that any pending writes to the fields of the object in acct.balance are also written to main memory.

most popular answer:

You are correct.

please research this code:

public class VolatileTest {

    static/* volatile */boolean done = false;

    public VolatileTest() {
        synchronized (this) {

        }

    }

    public static void main(String[] args) throws Exception {
        Runnable waiter = new Runnable() {
            public void run() {
                while (!done)
                    ;
                System.out.println("Exited loop");

            }
        };
        new Thread(waiter).start();
        Thread.sleep(100); // wait for JIT compilation
        synchronized (VolatileTest.class) {
            done = true;
        }
        System.out.println("done is true ");
    }

}

On my pc this program doesn't terminate.

Thus I think that

  1. if I change volatile variable I will see actual value in another thread for any outstanding everywhere!
  2. if I change variable in synchronized section with monitor "A" I will see actual value only in synchronized section with monitor "A"(for example in another thread)

Am I correct ?

Was it helpful?

Solution

  1. Yes, that is true because volatile write happens-before written value can be read from the variable.
  2. Not exactly. There is a guarantee that another thread synchronized on the same monitor will see the updated value, because monitor release happens-before same monitor acquire by another thread. Without acquiring the same monitor, the other threads may see the updated value. The "only" in your formulation is too strong :)

OTHER TIPS

You are correct)

The memory model is described here: Java Memory Model

In particular, it states:

An unlock on a monitor happens-before every subsequent lock on that monitor.

AND

A write to a volatile field (§8.3.1.4) happens-before every subsequent read of that field.

As such, only locks and unlocks on the same monitor will behave how you want, also all writes and reads of a volatile variable. Hence your program may not terminate, as you read without locking said monitor and there is no happens-before relationship.

One thing to note (and this is the reason multithreading bugs are so annoying):
You MAY see the change in other threads. Or may not. On most architectures you will likely see it during normal processing, and maybe a bug will manifest during high load, making it difficult to reproduce. The JVM does not give any guarantees what and when will see it if there is no happens-before (i.e. volatile, synchronized, in same thread or the other cases as in the link), but tries it's best to run smoothly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top