Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 976
agienka Avatar asked Jun 18 '17 11:06

agienka


1 Answers

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();
    }
}
like image 72
folkol Avatar answered Sep 30 '22 15:09

folkol