java并发编程实战《发布与逸出》

一、概念

            发布 (publish):指一个对象能够在当前作用域之外的代码中使用。
        
         逸出(escape)  : 指一个对象尚未构造完成已经发布,该对象引用被发布。

二、逸出方式

    1、共有静态变量引用方式逸出
          
public static Set<Secret> knownSecrets ;
public void  initialize(){
  knownSecrets =  new HashSet<Secret>();
}





     
     

将对象放入静态变量中,任何类和线程都可以看到该对象,都可以遍历上述集合来获得该对象的引用


      
      

     
     



     
     

2、非私有方法返回引用方式逸出

class UnsafeStates {
         private String[] states = new String[]{"AK", "AL"};
         public String[] getStates() {
              return states;
         }
      }

私有变量通过非私有方法发布出去导致该私有变量逸出当前作用域,成为了共有变量, 任何调用者都可以修改此变量的内容

3、this逸出

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




这种发布是发布一个内部的实现类,ThisEscape发布EventListener时,隐含地发布了ThisEscape实例本身,因为这个内部类中含有ThisEscape的实例并且调用了ThisEscape的doSomething 方法,此时ThisEscape对象还未构造完成,已经对外发布了该实例的引用。在构造尚未完成时就发布了对象引用成为不正确构造



        
        

注意:不要在构造函数中使this逸出
在构造过程中使this逸出的一个常见错误是:在构造函数中启动一个新线程。当对象在构造函数中
创建一个 线程时,无论是显式创建(通过将他传给构造函数即构造函数中使用了对象引用)还是
隐式创建(由于Thread或Runnable是该对象的一个内部类),this引用都会被新创建的线程共享。
在对象未完成构造之前,新线程就可以看到它。在构造函数中创建线程并没有错,但不要立刻
启动它,而是通过一个start或initialize方法来启动(详解:服务生命周期的内容)。



书中给出解决该种逸出的方法

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





一个私有的构造函数和一个共有工厂方法,避免不正确构造。。







        
        

       
       
 
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值