1. 概念

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

例如:将一个指向该对象的引用保到其他代码可以访问的地方,或者在某个非私有的方法中返回该引用,或者将引用传递到其他类的方法中。

发布内部状态可能会破坏封装性,并使得程序难以维持不变性条件。

“逸出(Escape)”:当某个不应该被发布的对象被发布时,这种情况称为逸出。

2. 对象发布的方式

发布对象的最简单方法是将对象的引用保存到一个公有的静态变量中,以便任何类和线程都能看见该对象。如下代码所示,在initialize方法中实例化一个新的HashSet对象,并将对象的引用保存到knownSecrets中以发布该对象。

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

如果从非私有方法中返回一个引用,那么同样会发布返回的对象,如下代码所示,UnsafeStates发布了本应为私有的状态数组。

class UnsafeStates {private String[] states = new String[]{"HSH", "KK" ... }public String[] getStates() { return states; }
}

还有一种发布对象或其内部状态的机制就是发布一个内部类的实例。如第三节中所示。

当发布一个对象时,在该对象中的非私有域中引用的所有对象同样会被发布。如果一个已经发布的对象能够通过非私有的变量引用和方法调用到达其他的对象,那么这些对象也都会发布。

3. 逸出

当发布了一个对象后,无法知道哪些代码会执行,也不知道在外部方法中究竟会发布这个对象,还是会保留对象的引用并在随后又另一个线程使用。无论其他的线程会对已发布的引用执行何种操作,其实都不重要,因为误用该引用的风险始终存在。当某个对象逸出后,你必须假设有某个类或线程可能会误用该对象。这正是需要使用封装的最主要原因:封装能够使得对程序的正确性进行分析变得可能,并使得无意中破坏设计约束条件变得更难。

this引用逸出

在下面的代码中,当ThisEscape发布EventListener时,也隐含地发布了ThisEscape实例本身,因为在这个内部类的实例中包含了对ThisEscape实例的隐含引用。

public class ThisEscape {public ThisEscape(EventSource source) {source.registerListener(new EventListener() {@Overridepublic void onEvent(Event event) {doSomething(event);}});}public static void main(String[] args) {new ThisEscape(new EventSource());}private void doSomething(Event event){System.out.println("doSomething");}
}
public class EventSource {public void registerListener(EventListener eventListener){eventListener.onEvent(new Event());}
}
public interface EventListener {void onEvent(Event event);
}
public class Event {
}

不要在构造过程中使this引用逸出。

在ThisEscape中给出了逸出的一个特殊示例,即this引用在构造函数中逸出。当内部的EventListener实例发布时,在外部封装的ThisEscape实例也逸出了。当且仅当对象的构造函数返回时,对象才处于可预测的和一致的状态。因此,当从对象的构造函数中发布对象时,只是发布了一个尚未构造完成的对象。即使发布对象的语句位于构造函数的最后一行也是如此。如果this引用在构造过程中逸出,那么这种对象就被认为是不正确构造。

Java对象的发布与逸出相关推荐

  1. 并发编程之对象的发布和逸出

    一.对象的发布和逸出 发布(publish)对象意味着其作用域之外的代码可以访问操作此对象.例如将对象的引用保存到其他代码可以访问的地方,或者在非私有的方法中返回对象的引用,或者将对象的引用传递给其他 ...

  2. 对象的发布与逸出简单理解

    目录 对象的发布与逸出简单理解 定义 实战 对象的发布与逸出简单理解 最近来看<并发编程实战>,第3.2节有点疑问,记录一下. 定义 发布:发布(Publish)一个对象的意思是指,使对象 ...

  3. 《java并发编程实战》读书笔记二 对象的发布与逸出

    概念 发布(publishing): 发布一个对象的意思是使它能够被当前范围之外的代码所使用.比如将一个引用存储到其他代码可以访问的地方,在一个非私有的方法中返回这个引用,也可以把它传递到其他类的方法 ...

  4. 并发编程-08安全发布对象之发布与逸出

    文章目录 脑图 概念 示例 不安全的发布对象Demo 对象逸出Demo 小结 代码 脑图 概念 发布对象: 使一个对象能够被当前范围之外的代码所使用,日常开发中比较常见的比如通过类的非私有方法返回对象 ...

  5. 多线程5:对象的发布与逸出(线程安全性)

    发布:使对象能够在当前作用域之外的代码中使用 逸出:当某个不该被发布的对象被发布时,这种情况称为逸出 发布内部状态将会破坏封装性,并使得程序难以维持不变性条件 当某个对象逸出后,必须对程序进行分析,以 ...

  6. 逸出 java_【java】知识系谱-基础篇-线程-发布、逸出

    java并发编程实战的解释,不够详细,尤其this引用逸出让人理解有些费解,java并发编程实战里面的内容就直接拷贝过来 发布:使对象能够在当前作用域之外的代码中使用 逸出:当某个不该被发布的对象被发 ...

  7. java 发布和逸出

    [转载]:http://www.2cto.com/kf/201310/247738.html 前言 多线程并发环境下,线程安全极为重要.往往一些问题的发生都是由于不正确的发布了对象造成了对象逸出而引起 ...

  8. java中的逸出是什么意思,发布和逸出-构造过程中使this引用逸出

    1.什么是this对象 this就是该对象实例本身 2.何为发布和逸出 发布,就是把对象暴露给他人,这就是为什么会需要用到封装,不能预料到其他第三方会如何使用对象,一不小心可能就被玩坏了 逸出,把不应 ...

  9. 多线程核心8-3:线程三大安全问题之发布与逸出

    发布与逸出的概念 发布:对象能够在作用域范围外被使用,则这个对象被发布出去了 逸出:被发布到了不该发布的地方,以下是逸出的两种情况: 方法返回一个private对象 未完成初始化(构造函数还未执行完毕 ...

最新文章

  1. oneinstack
  2. CSS之布局(默认样式)
  3. 谷歌、亚马逊、微软、IBM…这些巨头都已如何通过AI赚到钱了?
  4. 第二篇:salt-api使用填坑指南
  5. Ubuntu 16.04安装unrar解压RAR文件
  6. mysql触发器删除同步_MySQL 触发器例子(两张表同步增加和删除)
  7. Linux挂载Linux共享文件夹
  8. 3D 音频技术产品介绍(1):Iosono the future of spatial audio
  9. Beetle在TCP通讯中使用协议分析器和自定义协议对象
  10. 通过这本拼图学习Bash
  11. 一次失败的做题经历(HDU2112)
  12. Java测试用例简介
  13. 蚂蚁课堂学习笔记之springAop和Ioc
  14. 第115页的gtk+编程例子——最简单的进度条2附带使用Anjuta写gtk程序的步骤
  15. A-level成绩BBB能申英国哪些大学?
  16. 2020.2.18 大一寒假训练十一(set)
  17. 究竟新买的手机电池第一次要充多久的电
  18. singleTask 与 taskAffinity 缠绵的那些事
  19. 数据结构与算法 实验5 树、二叉树和森林的基本操作
  20. 百度移动优化:关于移动端点击图片放大有多少人注意?

热门文章

  1. python书籍收集
  2. 计算机网络——PPP协议与HDLC协议
  3. fortran:使用IMSL函数库计算第一/二类完全椭圆积分
  4. HDU-1207 汉诺塔II
  5. 数据迁移同步平台CloudCanal免费社区版正式发布,诸多功能特性等你体验!
  6. Spring 系列:Spring AOP 中@Pointcut的用法(多个Pointcut)
  7. Win10如何删除Windowsapps文件夹?Windowsapps文件夹删除方法
  8. github 这个网站到底有什么用?
  9. 强化学习(一)-->隐马尔科夫模型HMM-->HMM模型基础
  10. rock64搭建superset(适用于其他linux服务器)