Re: JavaMemoryModel: Unsynchronized read as an optimization

From: Robert Munyer (
Date: Mon Dec 18 2000 - 20:22:40 EST

On 12/18/00, David Holmes <> wrote:

>> Thread 3 is allowed to load helper and/or its fields
>> from main memory BEFORE it enters the getHelper method, and
>> then use those old values after it sees that helperExists is true.
> If you interpret the spec such that it allows for a thread to read a value
> an arbitrary amount of time before it is used, and that such reads can occur
> in any order - then you are correct. But that is about as loose an
> interpretation of the spec that is possible. But we've long since given up
> arguing over how Ch17 should be interpreted.

Isn't my sentence which you quoted above exactly what happens on the Alpha?
A thread uses a value from its own working memory, which is older than the
value in main memory? I've never used an Alpha, so I could be wrong, but I
thought that was why there's no fix for doing unsynchronized reads on Alpha.

>> That's why the Boolean configuration parameter is necessary, and why it
>> must not be set to "true" if the program is running on certain machines
>> (Alpha, and possibly others?).
> Surely if you have ascertained whether or not it is correct to set the
> parameter to true then the complex logic is unnecessary - as Bill already
> suggested? The runtime actions of the code do not prove anything so you
> should be able to do something like:
> if (!Config.UNSYNC_READS_ALLOWED || helper == null)
> synchronized(this) {
> if (helper == null)
> helper = new Helper();
> }
> }
> return helper;

No, there's a big difference. In your code above, it's possible for the
write of the variable "helper" to arrive at the main memory before all of
the writes performed by the constructor have arrived. In my code, all the
writes performed by the constructor are guaranteed to arrive at the main
memory before the variable "helperExists" is set to true.

> Of course, Config.UNSYNC_READS_ALLOWED must be volatile to ensure the
> correct value of it is seen.

In my code the flag does not have to be volatile, unless I want to change it
from "true" to "false" while the program is running. There is no reason I
would ever want to do that.

>> If I understand you correctly, it sounds like under the new
>> memory model, the code above will still work if the Boolean is set to
>> "false" -- but it won't run as fast as code that has been custom-designed
>> for the new spec by using "volatile."
> Under the new memory model the code will fail in both cases. In the case of
> "false" the code will fail if the thread sees "true" instead - because it
> will be allowed to see garbage when no synchronisation is used.

I think you're describing something that can't happen. Neither of the two
Booleans in my code ever changes from "true" to "false." A thread can see a
stale "false" value, but a stale "true" value is impossible. The new memory
model won't drop the "not out of thin air" rule, will it?

> If helperExists is made volatile then that can't happen - but under the new
> spec, when it is volatile you won't need the original code anyway.
>> Note, however, that any such code using volatile would
>> need to have a similar Boolean configuration parameter, if you want it to
>> be backward-compatible with JVMs that use the original Chapter 17 memory
>> model.
> Well if you can find a VM that implements Ch17 as it stands and which runs
> on a weakly ordered machine - then you are probably right. In practice I
> don't think there is such a beast.

I'm not sure I understand what you mean. I was trying to say that if you
write some code that takes advantage of the new volatile semantics, you will
also have to provide a way to switch back to using synchronize, if you want
your code to be able to run on old JVMs as well. Is that incorrect?

-- Robert Munyer <>

JavaMemoryModel mailing list -

This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:29 EDT