• 隐式使用This 引用逸出


           发布(Publish)一个对象是指使对象能够在当前作用域之外的代码中被使用。例如将指向该对象的引用保存到其他代码可以访问到的地方 ,或者在一个非私有的方法中返回一个对象的引用或者将该引用传递到其他类的方法中。当发布一个对象时,在该对象的非私有域中的引用同样被发布出去,一般来说如果一个已经发布的对象能够通过非私有的变量和方法调用到其他的对象那么这个对象也被发布。

           逸出(Escape)是指 一个比应该被发布的对象被发布出去。

    在 《Java Concurrency in Practice》中关于隐式使用This 引用逸出的示例,比较难以理解如何逸出。ThisEscape发布EventListener时,也隐含地发布了ThisEscape实例本身,因为在这个内部类的实例中包含了对ThisEscape 实例的隐含引用。这个个人的理解代码是:

    /**
     *
     * @author zhangwei_david
     * @version $Id: ThisEscape.java, v 0.1 2014年11月3日 上午9:37:54 zhangwei_david Exp $
     */
    public class ThisEscape {
        private String name = null;
    
        public ThisEscape(EventSource source) {
            source.registerListener(new EventListener() {
    
                public void onEvent(Event event) {
                    doSomething(event);
                }
    
            });
            name = "TEST";
        }
    
        /**
         *
         * @param event
         */
        protected void doSomething(Event event) {
            System.out.println(name.toString());
        }
    }
    import java.awt.Event;
    
    /**
     * 
     * @author zhangwei_david
     * @version $Id: Listener.java, v 0.1 2014年11月3日 上午9:40:13 zhangwei_david Exp $
     */
    public interface EventListener {
        public void onEvent(Event event);
    
    }
    /**
     *
     * @author zhangwei_david
     * @version $Id: EventSource.java, v 0.1 2014年11月3日 上午9:38:40 zhangwei_david Exp $
     */
    public class EventSource {
    
        public void registerListener(EventListener listener) {
            listener.onEvent(null);
        }
    
    }
    /**
     *
     * @author zhangwei_david
     * @version $Id: Client.java, v 0.1 2014年11月3日 上午9:45:48 zhangwei_david Exp $
     */
    public class Client {
    
        /**
         *
         * @param args
         * @throws InterruptedException
         */
        public static void main(String[] args) throws InterruptedException {
            EventSource es = new EventSource();
            new ThisEscape(es);
    
        }
    
    }
    

     运行的结果是:

    Exception in thread "main" java.lang.NullPointerException
    	at com.cathy.demo.concurrency.escape.ThisEscape.doSomething(ThisEscape.java:33)
    	at com.cathy.demo.concurrency.escape.ThisEscape$1.onEvent(ThisEscape.java:21)
    	at com.cathy.demo.concurrency.escape.EventSource.registerListener(EventSource.java:15)
    	at com.cathy.demo.concurrency.escape.ThisEscape.<init>(ThisEscape.java:18)
    	at com.cathy.demo.concurrency.escape.Client.main(Client.java:21)
    

      这个就是由于在name 初始化之前,就使用了ThisEscape实例,而此时实例尚未完成初始化。

     同样修改SafeListener

    import java.awt.Event;
    
    /**
     *
     * @author zhangwei_david
     * @version $Id: SafeListener.java, v 0.1 2014年11月3日 上午10:20:26 zhangwei_david Exp $
     */
    public class SafeListener {
    
        private final EventListener listener;
        private String              name = null;
    
        private SafeListener() {
            listener = new EventListener() {
    
                public void onEvent(Event event) {
                    doSomething();
                }
            };
            name = "TEST";
        }
    
        public static SafeListener newInstance(EventSource eventSource) {
            SafeListener safeListener = new SafeListener();
            eventSource.registerListener(safeListener.listener);
            return safeListener;
        }
    
        /**
         *
         */
        protected void doSomething() {
            System.out.println(name.toString());
        }
    }
    /**
     *
     * @author zhangwei_david
     * @version $Id: Client.java, v 0.1 2014年11月3日 上午9:45:48 zhangwei_david Exp $
     */
    public class Client {
    
        /**
         *
         * @param args
         * @throws InterruptedException
         */
        public static void main(String[] args) throws InterruptedException {
            EventSource es = new EventSource();
            //        new ThisEscape(es);
            SafeListener.newInstance(es);
        }
    
    }
    

     结果是:

    TEST
    
  • 相关阅读:
    使用RSA实现客户端和后台的非对称加密
    PHP异步并行网络扩展swoole安装
    rvm is not a function的解决方法
    python中的sort(),sorted()的用法
    RESTful框架中的Mixin中的五个类视图
    RESTful框架的API请求流程
    理解RESTful架构
    Django中的admin管理工具
    一个程序员的自我介绍--英文版
    Django中的认证系统
  • 原文地址:https://www.cnblogs.com/wei-zw/p/8797821.html
Copyright © 2020-2023  润新知