Welcome to the Java Memory Model mailing list. I sent out an
earlier message that appears (from my end) to have disappeared into
the bit bucket. If you got that message, it overlaps substantially
with this one (of course, I didn't save a copy of it, so I'm retyping
everything).
Recent developments:
* I've put up a web page http://www.cs.umd.edu/~pugh/java/memoryModel
for information about the memory model.
* Dan Scales did a preliminary investigation of the effects of Coherence
(a.k.a. "Reads kill"). It is available from the above web page. In brief,
for computationally intensive benchmarks (e.g., mpegaudio), it can be very
expensive.
* The fact the JLS requires Coherence and that the JVM's don't enforce it
is now listed as Javasoft Bug # 4242244.
* Discussions at Java Grande and Java One went well. The people at Sun seem to
be on board for replacing, rather than patching, the existing specification
(there was a little resistance from Bill Joy, but not too much -- once I
sit down with Guy and confirm the existing problems, Bill Joy should be on
board as well).
* No one I talked to at Java Grande and Java One is arguing for Coherence.
Unless an advocate puts forth a strong case for Coherence, I think we
can assume Coherence is dead.
* The people at Sun were opposed to doing a JSR (Java Specification Request),
at least at this point. The pointed out that when the JSR for generic
types was submitted, there were 3 concrete proposals with implementations
on the table.
* Talking with Josh Bloch and Gilad Bracha, we came up with the following
_ordered_ list of design goals for a new specification. The following is
informal and preliminary (to be improved later), and based on my notes
and interpretation of our discussion:
- Preserve existing safety guarantees of Java (e.g., no out of bound
array references, never using garbage as a pointer).
- Have a specification that we can reason about, and show whether or not
compiler analysis/transformations are valid with respect to it, and show
where (if any) memory barriers are required on specific architecture
memory models.
- Provide a new safety guarantee of initialization safety: Assuming you don't
shoot yourself in the foot, no code outside the construction of object X
should be able to see an incompletely constructed version of X. Shooting
yourself in the foot would involve storing a reference to X during the
construction of X, or passing a reference to X to a function during the
construction of X.
Note here that any constructors you chain to (via super() or this() calls)
are considered part of construction. If your super() shoots you in the foot,
you are shot.
This means, for example, that the following code should work:
class A {
private Point p;
synchronized void setPos(int x, int y) {
p = new Point(x, y);
}
double distanceToOrigin() {
// not synchronized
Point q = p;
return Math.sqrt(q.x*q.x + q.y*q.y);
}
}
Note that guaranteeing that you don't see a incompletely constructed object
doesn't guarantee that you won't see an inconsistent world state. For
example, in :
class Foo {
static private int nextID;
private int id;
public Foo() { synchronized(Foo.class) { id = ++nextID; } }
final public int age() { return id - nextID; }
}
there is nothing to guarantee that age returns a non-negative number
(even excluding the possibility of roll-over in ints). Consider the case
where thread 1 creates a Foo, publishes it (i.e., stores a references to
it in a memory location visible to another thread), thread 2 reads the
reference and then invokes age on it. In thread 2, the call to age can
be inlined (since the method is final), and the read of nextID can be
moved to before the load of the reference to the Foo object. Even making
nextID volatile wouldn't fix the problem (making both nextID and id
volatile would).
- Provide a synchronization idiom that provides a safe way for a thread
to construct an object, perform a series of updates on the object,
and then publish the object (store a reference to the object in memory
read by other threads). Other threads should then be able to read that
reference and see an object that reflects all of the modifications.
Importantly, the threads reading that reference should be able to do so
without any synchronization.
Once again, this guarantee only applies to seeing a consistent and complete
object. Other parts of the world state may be inconsistent.
- In code that doesn't involve locks or volatile variables, you should be
able to use as much as possible out of the standard set of compiler
techniques for single threaded code.
Comments?
* One issue we need to decide. The existing JLS and JVM Spec contain the
same specification, and the specification doesn't talk about either JVM
operations or the Java programming language. Instead, it talks about
use and assign actions, with no guidance as to how they are to be
interpreted.
There should be a memory model for both Java source programs and for
JVM programs. How should we specify it? I would hate to have two
different specifications, in two different styles, and then have to
prove a correspondence.
One suggestion is to give a memory model in terms of the JVM, and
find a formal way to say "For java source programs, the MM is
defined by the obvious translation to the JVM and then applying the
new JVM MM).
Comments?
Bill Pugh
-------------------------------
This is the JavaMemoryModel mailing list, managed by Majordomo 1.94.4.
To send a message to the list, email JavaMemoryModel@cs.umd.edu
To send a request to the list, email majordomo@cs.umd.edu and put
your request in the body of the message (use the request "help" for help).
For more information, visit http://www.cs.umd.edu/~pugh/java/memoryModel
This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:12 EDT