Implicit escape of “this” reference

One of the prerequisite in making an object immutable include making sure that the this reference isn’t allowed to escape during creation. This point is also referenced in the famous Java Concurrency In Practice book. Section 3.2 of the book states

A mechanism by which an object or its internal state can be published is to publish an inner class instance, as shown in ThisEscape in Listing 3.7. When ThisEscape publishes the EventListener, it implicitly publishes the enclosing ThisEscape instance as well, because inner class instances contain a hidden reference to the enclosing instance. ”

public class ThisEscape {
    private final int num;

    public ThisEscape(EventSource source) {
       source.registerListener(
          new EventListener() {
            public void onEvent(Event e) {
              doSomething(e);
           }
          });
      num = 42;
   }

   private void doSomething(Event e) {
     if (num != 42) {
       System.out.println("Race condition detected at " +
           new Date());
     }
   }
}

The above code creates issues in cases where for e.g. EventSource starts a concurrent execution which leads to the creation of the events before the constructor of ThisEscape completes. What this means is that the doSomething method gets called before the constructor of ThisEscape ends. Like any other method the doSomething() method, as shown above, could access the state of ThisEscape class assuming the object is in the consistent state.
To give an idea the EventSource code could look similar to

import java.util.concurrent.atomic.*;

public class EventSource extends Thread {
  private final AtomicReference<EventListener> listeners =
      new AtomicReference<EventListener>();

  public void run() {
    while (true) {
      EventListener listener = listeners.getAndSet(null);
      if (listener != null) {
        listener.onEvent(null);
      }
    }
  }

  public void registerListener(EventListener eventListener) {
    listeners.set(eventListener);
  }
}

So publishing an object from within its constructor can publish an incompletely constructed object. This is true even if the publication is that last statement in the constructor because the Java Memory Model (JMM) allows reordering of the statements. Thus the code might be optimized in such a way that the “this” reference escapes earlier.

To test the above explained race condition you could execute

 public class ThisEscapeTest {
   public static void main(String[] args) {
     EventSource es = new EventSource();
     es.start();
     while(true) {
       new ThisEscape(es);
     }
   }
 }

One of the solutions mentioned in the Java Concurrency In Practice book to the above problem is to use static factory method

public class SafeListener {
    private final EventListener listener;

    private SafeListener() {
        listener = new EventListener() {
            public void onEvent(Event e) {
                doSomething(e);
            }
        };
    }

    public static SafeListener newInstance(EventSource source) {
        SafeListener safe = new SafeListener();
        source.registerListener(safe.listener);
        return safe;
    }

}

Thanks to the Java Specialist news letters for providing details on this topic.

Advertisement

Posted on June 20, 2011, in java and tagged , . Bookmark the permalink. Leave a comment.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: