this引用逸出

来源:互联网 发布:mac磁盘可清除怎么清除 编辑:程序博客网 时间:2024/05/02 00:57

《Java 并发编程实践》3.2章里面的关于发布和逸出的部分,主要是构造过程中this引用的逸出。

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

这段代码的问题是对象逸出。

当我们声明一个非静态内部类时,编译器会添加对外部类的一个隐式引用。即非静态的内部类会持有外部类的一个隐式引用。

当我们实例化ThisEscape对象时,会调用source的registerListener方法,这时便启动了一个线程,而且这个线程持有了通过注册的内部类持有了外部ThisEscape对象引用,但此时ThisEscape对象却没有实例化完成(还没有返回一个引用),所以我们说,此时造成了一个this引用逸出,即还没有完成的实例化ThisEscape对象的动作,却已经暴露了对象的引用。其他线程访问还没有构造好的对象,可能会造成意料不到的问题。

书中给了解决方法,使用工厂方法防止this引用在构造过程中逸出。

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;    }}

不在构造方法中注册监听器,就不会创建持有外部引用的线程,this引用也就不会逸出。

原创粉丝点击