On May 27, 2004, at 1:33 PM, Jerry Schwarz wrote:
> At 09:24 PM 5/26/2004, Sylvia Else wrote:
>
> Consider this contrived scenario
>
> public class Outer {
> final int[] x = new int[1];
>
> class Inner {
> Inner() {
> x[0] = 42;
> }
>
> int get() {
> return x[0];
> }
> }
> }
>
> static Outer.Inner inner;
> Thread 1
> Outer outer = new Outer();
> inner = outer.new Inner();
>
> Thread 2
>
> int r = inner.get();
>
> Behaviour in question: r == 0;
>
> If the reference to the outer class is final, then the behaviour is
> prohibited, otherwise it is permitted. So which should it be?
>
>
>
> Permitted. There is no reason to treat this any differently than
>
> class Outer {
> static int[] x = new int[1];
> }
>
> class Inner {
> Inner() {
> Outer.x[0] = 42;
> }
> int get() {
> return Outer.x[0];
> }
> }
>
>
There is a difference in the semantics. Remember that (correct) reads
of final fields
are not only guaranteed to see the value the final field is initialized
to, but
also get transitive guarantees.
If this$0 is final, you can't get r = 0, assuming that
the reference through an inner object is the only way the thread
performing get() gains access
to the memory allocated for the x array. This is due to the transitive
guarantees for final fields.
-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel
This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:01:08 EDT