Re: JavaMemoryModel: non-finals with synchronized getters

From: Bill Pugh (pugh@cs.umd.edu)
Date: Sun Apr 01 2001 - 00:06:46 EST


At 6:04 PM -0800 3/31/01, Joseph Bowbeer wrote:
>A couple questions about final:
>
>Consider the following class, where the field 'x' is not final, but where
>the getX method is synchronized:
>
> class Foo {
> private int x;
> Foo() { x = 1; }
> synchronized int getX() { return x; }
> }
>
>Assume thread2 gets its hands on a reference to a new Foo object without
>using synchronization, as follows:
>
> class Bar {
> static Foo FOO;
> }
>
>Thread 1:
> Bar.FOO = new Foo();
>
>Thread 2:
> Foo foo = Bar.FOO;
> assert( foo == null || foo.getX() == 1 );
>
>Question: Is it possible for thread2 to see "getX() != 1"?

In our model, it is possible for thread2 to see foo.getX() == 0.

This can happen because the write of 1 to x is not properly
synchronized with regards to the read by thread 2.

In order to make this work in our semantics, you would need something
like an implicit lock associated with each constructor. But that
would bias code towards objects that use this as a monitor, when good
design often calls for the use of some other object as a monitor.

Among other points, not that in this example, the Foo object is only
synchronized on by a single thread. So a compiler should be able to
remove the synchronization.

In the CRF model, it is not possible to see foo.getX() == 0, even
without synchronization in the getX method. The CRF model makes the
same guarantees for both final and non-final fields as far as seeing
values written in the constructor.

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:31 EDT