The reason I find this behavior surprising is that when dealing with a
single CPU, the CPU is not causing the visibility issues. With a single CPU,
while the CPU may do all kinds of reordering, the CPU is also aware of what
reordering has happened and makes it look as if reordering never occurred.
With a single CPU you should never be able to tell if the CPU allows
reordering or not.
To see reordering on a uniprocessor machine, that means that the VM itself
is reordering writes. This surprised me since I don't think performance will
be improved by the VM reordering writes. It makes some since if the VM
literally implemented the JMM, and thus has per thread caches where it does
its work, and copies this data back to main memory. But if this was going
on, I would expect to catch the VM doing this more frequently. I also don't
see any good reasons for a VM to go to all the extra work it takes to cause
problems.
So I was wondering if anyone on the list would know what the Sun classic VMs
are doing to cause this, and if any other VMs have this property. The JMM
certainly makes this legal, but since it takes extra effort to cause
problems on a single CPU I did not expect to see it there.
As far as the Butenhof discussions go, they are very useful for
understanding the multiprocessor problem, and I understand these issues.
They don't address seeing this behavior on a uniprocessor.
Now the bonus question is, if you are running on a multiprocessor, and both
the CPUs and the VM is reordering writes, are the issues the same or do some
additional problems crop up?
--Paul
-----Original Message-----
From: David Holmes [mailto:dholmes@dstc.edu.au]
Sent: Wednesday, May 24, 2000 9:43 PM
To: Paul Jakubik
Cc: jmm
Subject: Re: JavaMemoryModel: Problem on single processor
> Anyone have thoughts on why double-check would fail on a single processor?
If the writes of the reference and the associated fields are reordered then
a second thread may see the reference as non-null but still see the fields
in their un-initialized state (at the point that the second thread sees the
fields the first thread has not yet exited the synchronised block).
Why this seems to be specific to a particular VM version - I guess it
depends on what code the JIT produces.
As you noted in your emails the double-check pattern suffers from two
potential error sources: write reordering and read-reordering. Write
reordering can occur even on uni-processors. A solution to the write
reordering problem is to add an extra step to the write path and use a
second synchronized block:
if (singletons[i] == null) {
synchronized(singletons[i]) {
synchronized (singletons[i]) {
temp = new Singleton();
} // temp fields are now forced to memory: assuming the JVM obeys MM
rules
// when dealing with recursive locks.
singletons[i] = temp;
} // reference now forced to main memory
}
This, of course, does not solve potential read-reordering problems.
Try and dig out an archive of Dave Butenhof's various postings to
comp.programming.threads on this subject, for a non Java specific view of
the
problem.
David
-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel
-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel
This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:25 EDT