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

一、概念

     发布 (publish):指一个对象能够在当前作用域之外的代码中使用。

     逸出(escape)  : 指一个对象尚未构造完成已经发布,该对象引用被发布。

二、逸出方式

1、共有静态变量引用方式逸出

public static Set knownSecrets ;
public void initialize(){
knownSecrets = new HashSet();
}

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值