Re: JavaMemoryModel: Thread starting in constructors

From: Alexander Terekhov (TEREKHOV@de.ibm.com)
Date: Tue Mar 12 2002 - 11:37:32 EST


> ... But so do other anomalies.

and how does this relates to:

http://www.cs.umd.edu/~pugh/java/memoryModel/semantics.pdf

"If thread T1 starts thread T2, then all actions visible
 to T1 at the time it starts T2 become visible to T2
 before T2 starts. Similarly, if T1 joins with T2 (waits
 for T2 to terminate), then all accesses visible to T2
 when T2 terminates are visible to T1 after the join
 completes."

<?!>

regards,
alexander.

Jerry Schwarz <jschwarz@us.oracle.com>@cs.umd.edu on 03/12/2002 04:46:24 PM

Please respond to Jerry Schwarz <jschwarz@us.oracle.com>

Sent by: owner-javamemorymodel@cs.umd.edu

To: "Joshua Bloch" <joshua.bloch@sun.com>, <javamemorymodel@cs.umd.edu>,
       "Bill Pugh" <pugh@cs.umd.edu>
cc:
Subject: Re: JavaMemoryModel: Thread starting in constructors

At 07:57 PM 3/11/2002, Joshua Bloch wrote:
>Bill,
>
> > OK, this is just a simple example of something I'm trying to fine tune:
> >
> > class A {
> > int x;
> > final int y;
> > public A(int a, int b) {
> > x = a;
> > y = b;
> > new Thread() {
> > public void run() {
> > System.out.println("x = " + x + ", y = " + y);
> > }}.start();
> > }
> > }
> >
> > Assume someone invokes new A(1,2). Which of the might occur?
> >
> > a) prints x = 1, y = 2
> > b) prints x = 0, y = 0
> > c) prints x = 0, y = 2
> > d) prints x = 1, y = 0
> > e) the thread started in the constructor throws a NullPointerException
>
> Clearly I'm being dense here, but why is anything other than (a)
legal?
>I always thought that there was implicit synchronization between a thread
>that started a thread and the thread that it started. If anything besides
>(a) is legal, people will be mightily confused.
> Josh

That was my reaction too, but I slept on it overnight and I think I see a
subtlety that I overlooked yesterday. When is A.y read? Could it be read
by the constructor of the Thread instead of by the run method.

This question can be illustrated without threads. Consider the following
example

   public class S {
     public final int x;
     S() { x = ... ; }
     ...
   }

   public class U {
     private S s;
     public U(S s) { this.s = s; }
     public int f() { return s.x; }
   }

Is a compiler allowed to transform the definition of U into

   public class U' {
     private int s_x;
     public U(S s) { this.s_x = s.x ; }
     public int f() { return s_x; }
   }

Obviously, this couldn't be allowed if s.x were not final, but does the
special semantics of final allow it? I would like to say yes because this
is potentially a significant optimization. The relevance to Bill's example
is that if this transformation were allowed on the anonymous Thread class
then

> d) prints x = 1, y = 0

becomes possible.

But so do other anomalies. In particular what if U's are used in
constructors of S. Let's modify S a little

   public class S {
     public final int x;
     private U u;
     public S() {
       u = new(this);
       x = ...; // non-zero value
     }
     public int f() { return u.f(); }
   }

With the optimization in place S.f will return 0. But I don't see any way
I can justify S.f returning 0, so I guess the optimization can't be
allowed. And so, (d) isn't allowed either.

   -- Jerry Schwarz

-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel

-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel



This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:38 EDT