Java并发编程实战 读书笔记(二)

关于发布和逸出

并发编程实践中,this引用逃逸("this"escape)是指对象还没有构造完成,它的this引用就被发布出去了。这是危及到线程安全的,因为其他线程有可能通过这个逸出的引用访问到“初始化了一半”的对象(partially-constructed object)。这样就会出现某些线程中看到该对象的状态是没初始化完的状态,而在另外一些线程看到的却是已经初始化完的状态,这种不一致性是不确定的,程序也会因此而产生一些无法预知的并发错误。在说明并发编程中如何避免this引用逸出之前,我们先看看一个对象是如何产生this引用逸出的。
 
一、this引用逸出是如何产生的
     正如代码清单1所示,ThisEscape在构造函数中引入了一个内部类EventListener,而内部类会自动的持有其外部类(这里是ThisEscape)的this引用。source.registerListener会将内部类发布出去,从而ThisEscape.this引用也随着内部类被发布了出去。但此时ThisEscape对象还没有构造完成 —— id已被赋值为1,但name还没被赋值,仍然为null。
          
     代码清单1 this引用逸出示例
  
public class ThisEscape {

 

      public final int id;

      public final String name;

      public ThisEscape(EventSource<EventListener> source) {

            id = 1;

            source.registerListener(new EventListener() {

                  public void onEvent(Object obj) {

                        System.out.println("id: "+ThisEscape.this.id);

                        System.out.println("name: "+ThisEscape.this.name);

                  }

            });

            name = "xingpc";

             

      }

  }

二、如何避免this引用逸出        上文演示了由内部类导致的this引用逸出是怎样产生的。它需要满足两个条件:一个是在构造函数中创建内部类(EventListener),另一个是在构造函数中就把这个内部类给发布了出去(source.registerListener)。因此,我们要防止这一类this引用逸出的方法就是避免让这两个条件同时出现。也就是说,如果要在构造函数中创建内部类,那么就不能在构造函数中把他发布了,应该在构造函数外发布,即等构造函数执行完毕,初始化工作已全部完成,再发布内部类。

public class ThisSafe {

 

      public final int id;

      public final String name;

      private final EventListener listener;

      

      private ThisSafe() {

            id = 1;

            listener = new EventListener(){

                  public void onEvent(Object obj) {

                        System.out.println("id: "+ThisSafe.this.id);

                        System.out.println("name: "+ThisSafe.this.name);

                  }

            };

            name = "flysqrlboy";

      }

      

      public static ThisSafe getInstance(EventSource<EventListener> source) {

            ThisSafe safe = new ThisSafe();

            source.registerListener(safe.listener);

            return safe;

      }

      

      

}
 
 
 

猜你喜欢

转载自www.cnblogs.com/xingpengcheng/p/10526353.html
今日推荐