Most of the (interesting) discussion of this example has focused on
the value of f that can be seen when a reference is leaked in the
constructor. But suppose we got rid of badHolder and eliminated that
problem. Wouldn't this program have a race on goodHolder
itself unless something is done to create hb edges? For example,
by making goodHolder volatile, or ensuring that goodHolder is assigned
by some thread before other threads that read it are started, or
otherwise "safely publish" the reference? But if we still need
safe publication, then the special semantics for final fields don't
add anything. What am I missing?
In this example, safe publication is needed (it is safe when
goodHolder is volatile)
class FinalHolder {
static [volatile] FinalHolder goodHolder;
final int f;
FinalHolder() {
f = 1;
}
void printFinal() {
System.out.println(f);
}
Thread1:
Thread2.start();
goodHolder = new FinalHolder();
Thread2:
while(goodHolder==null){}
//termination guaranteed only if goodHolder volatile
goodHolder.print();
//if thread gets here, it will print 1 due to
//correct construction (no leak of ref from consructor)
//and final field semantics.
//But if goodHolder volatile, f doesn't need to be
//final except to ensure that the value is not modified--special
//treatment in the memory model is not needed.
Thanks,
Beverly Sanders
_______________________________________________
Concurrency-interest mailing list
Concurrency-interest@...
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest