Understanding Java memory model during context switches

Viewed 94

Recently in a conference talk the following was used as an example to demonstrate the Java memory model in a multithreaded environment.

public class A {

    public static boolean done;

    public static void main(String[] args) throws InterruptedException {
        done = false;
        new Thread(new Runnable(){
            public void run() {
                System.out.println("running...");

                int count = 0;
                while (!done) {
                    count++;
                }

                System.out.println("Exiting thread");
            }
        }).start();

        System.out.println("in main...");
        Thread.sleep(2000);

        System.out.println("setting done to true");
        done = true;
    }
}

I understand that the new thread created in above code will never exit because of done variable being cached in Thread's local cache. And a proper solution will be to make the done variable volatile.

But if inside the while loop, we call Thread.sleep() as follows

    while (!done) {
        count++;
        try {Thread.sleep(0);} catch(Exception e){}
    }

then the Thread successfully exits.

My understanding is that because of sleep(0) a context switch will occur that will invalidate the cache entries, so each time the updated value of done is retrieved. Is my understanding correct? Also is this behaviour dependent on the number of cores of the machine?

1 Answers

Java Language Specification clearly states that Thread::sleep does not have any happens-before semantics (and those are the only one you want to reason with):

... Thread.sleep nor Thread.yield have any synchronization semantics...

As such whatever output you "happen" to see using it, are not guaranteed by the specification. The only guarantees you have is when done is volatile, again, because the JLS gives you such guarantees.

Your reasoning about a correctly synchronized program must be backed against happens-before, context switch, caches, etc. are irrelevant.

Related