Search code examples
javaconcurrency

Java escaping reference to 'this'


I started reading Java Concurrency in Practice and I came across the following example (this is a negative example - shows bad practice):

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

The author in the book writes:

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.

When I think about the usage of such code, I could do something like so:

EventSource eventSource = new EventSource();
ThisEscape thisEscape = new ThisEscape(eventSource);

and I can get the reference to the registered EventListener, but what does it mean that I could obtain the reference to the enclosing ThisEscape instance?

Could someone give me an example of such a behaviour? What is the use case?


Solution

  • The problem with escaping this references is that code in other threads might start interacting with the object before the constructor is finished constructing it.

    Consider this example:

    public class ThisEscape
    {
        Foo foo;
        public ThisEscape(EventSource source) {
            source.registerListener(new EventListener()
            {
                public void onEvent(Event e) {
                    doSomething(e);
                }
            });
    
            // Possible Thread Context switch
    
            // More important initialization
            foo = new Foo();
        }
    
        public void doSomething(Event e) {
            // Might throw NullPointerException, by being invoked
            // through the EventListener before foo is initialized
            foo.bar();
        }
    }