[concurrency-interest] Escaping "this" reference in constructors

Kasper Nielsen kav at it.edu
Thu Oct 19 06:11:28 EDT 2006


Hi,

I'm well aware of the problems with letting the "this" reference escape 
in a constructor. However sometimes it is just too tempting.
Consider this small example,

class MainService {
     private final ServiceA a;
     private final ServiceB b;
     MainService() {
         a = new ServiceA(this);
         b = new ServiceB();
     }
     void start() {b.set(this);}
}
class ServiceA {
     private final MainService m;
     ServiceA(MainService m) {this.m = m;}
}
class ServiceB  {
     private volatile MainService m;
     public void set(MainService m) {this.m = m;}
}

I would rather not use ServiceB, because of the volatile field. I make a 
fair amount of callback from ServiceA/B into MainService. So i'd rather 
not want to pay for a volatile field. (yes I know they are cheap)

I guess ServiceA is okay in this situation because I have 100 % control 
of the code.


Now consider a slightly different implementation of MainService

class MainService2 {
     private final Service a;
     MainService2(Class<? extends Service> c) throws Exception {
         a = c.getConstructor(MainService2.class).newInstance(this);
     }
}
interface Service {
   void start();
}
class ServiceImpl implements Service {
     private final MainService2 m;
     ServiceA(MainService2 m) {this.m = m;}
     public void start() {//do dangerous stuff on MainService2}
}

Here the user specifies the type of the service to the constructor of 
MainService2 and there is no telling what type of service the user 
specifies only that it is some subtype of Service.

Would it be fine if I made something like this part of the Service 
interface contract: *No* operations are allowed to be invoked on 
MainService2 in the constructor. The only allowed use of MainService2 is 
storing the reference into a field.

Am I shooting myself in the foot?

- Kasper


More information about the Concurrency-interest mailing list