OK, consider the following example:
Example 1:
class A {
static A curr;
static A prev;
A myPrev;
A() {
myPrev = prev;
}
static void T1() {
curr = new A();
}
static void T2() {
prev = curr;
}
}
Now, for this (incorrectly synchronized) example, it is perfectly
possible to generate an A object who's myPrev field points to itself
(T1 could inline the constructor and reorder the read of A.prev and
and write of A.curr).
OK, now what if A has a final field:
Example 2:
class A {
static A curr;
static A prev;
A myPrev;
private final int x;
A() {
myPrev = prev;
x = 42; // it actually doesn't matter which statement comes first
}
static void T1() {
curr = new A();
}
static void T2() {
prev = curr;
}
}
OK, the simple implementation (and semantics) of final fields
involves putting a Write/Write membar at the end of constructors for
classes with final fields. Since A has a final field x, the membar
needs to be placed. However, since no one ever reads the final field,
maybe we don't need the memory barrier.
In my formalism, the question is whether an initWrite of a reference
can be moved above an earlier freezeFinal. If I want to allow that
reordering, yet still preserve all of the important properties of
final fields, I am going to have to do some very complicated
gymnastics in my semantics.
QUESTION: Is it OK if in Example 2, the addition of an (unused) final
field prevents the reordering of the read of A.prev and the write of
A.curr?
How do people feel about this? I don't like the idea that somebody
might start depending on such weird side effects of constructing
objects with final fields. On the other hand, my semantics are
already complicated enough.
Bill
-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel
This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:34 EDT