目录

  • 对象的发布与逸出简单理解
    • 定义
    • 实战

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

最近来看《并发编程实战》,第3.2节有点疑问,记录一下。

定义

  • 发布:发布(Publish)一个对象的意思是指,使对象在当前作用域之外的代码中使用。
  • 逸出:如果再对象构造完全之前就发布该对象,就会破坏线程安全性。当某个不应该发布的对象被发布时,这种情况就被成为逸出(Escape)

实战

发布比较好理解,像单例模式,还有做初始化操作的时候,都是这样。比如像书中代码片段

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

此时的knownSecrets对象的作用域保证任意代码可以遍历这个集合,并且获得这个引用。

但是如果这里是是一个私有对象的时候,就会超过他定义的所在的作用域,即当前这个类。

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

如果有以下代码修改了

  String[] myStates = getStates();myStates[0] ="ABC"//最后结果数组第一个被改为"ABC"

当一个对象传递给某个外部方法时,就相当于发布了这个对象。所以也会保留这个对象的引用,你在修改这个对象的引用的时候,私有的那个变量也会改变。这样就会带来一个风险。在构造方法没有完成的情况下,把对象发布出去,这就造成隐式地this引用逸出。同样还是用书中的案例,我这里增加了一个局部变量num,通过查看这个num值可以看出问题。

public class ThisEscape {//当前类的私有变量private int num;//事件源类private static class EventSource {public void registerListener(EventListener eventListener){eventListener.onEvent(new Event());//sth}}//事件类private static class Event{}//时间监听类private interface EventListener{void onEvent(Event event);}//------------------------------------------------------------------//主要是这个构造方法。。。public ThisEscape(EventSource eventSource){eventSource.registerListener(new EventListener() {@Overridepublic void onEvent(Event event) {//这里,内部类实现中暴露了当前类的私有变量,而且是在初始化以前System.out.println("内部方法的num:"+num);}});//继续初始化操作,给num赋值,然后构造方法结束num=10;}public static void main(String[] args) {ThisEscape threadTest7 = new ThisEscape(new EventSource());System.out.println("初始化完毕后的num:"+threadTest7.num);}
}

这个地方最后的结果

内部方法的num:0
初始化完毕后的num:10

这个num在我们匿名方法中在初始化对象钱就拿到了this,也拿到了没有初始化的num的值0。这样就会带来很大的风险。同时,这个也被称为不正确构造

书中也给我们提供了一个工厂方法来解决这个this在引用构造逸出的问题,我按照上面的例子,增加了一个Private作用范围的常量来接收

public class ThreadTest8 {//当前类的私有变量private int num ;//使用final修饰private final EventListener listener;// 准备类private static class EventSource {public void registerListener(EventListener eventListener){eventListener.onEvent(new Event());System.out.println(eventListener);//sth}}// 准备类private static class Event{}// 准备类private interface EventListener{void onEvent(Event event);}//----------------------------------------------//主要是这个构造方法。。。//私有化构造方法//限定这个构造方法的作用域private ThreadTest8(){listener = new EventListener() {@Overridepublic void onEvent(Event event) {//内部类实现中暴露了当前类的私有变量,但是作用域限制了当前类System.out.println("内部方法的num:"+num);}};num = 10;}public static ThreadTest8 newInstance(EventSource eventSource){ThreadTest8 threadTest8 = new ThreadTest8();eventSource.registerListener(threadTest8.listener);return threadTest8;}public static void main(String[] args) {ThreadTest8 threadTest8 = newInstance(new EventSource());System.out.println("初始化完毕后的num:"+threadTest8.num);}
}

这个时候,最后的结果都会是10了。

内部方法的num:10
初始化完毕后的num:10

因为在构造方法中启动一个线程,无论是显示的还是隐式的,this引用都会被新的线程共享。(内部类的关系)。所以在对象构造前就可以看到他,虽然在创建这个新线程的时候没有错误,所以在这个时候不要立即启动,等待初始化结束后再去调用这个新的线程。最后的工厂方法也是避免了不正确的构造来避免this引用的逸出。

对象的发布与逸出简单理解相关推荐

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

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

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

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

  3. Java对象的发布与逸出

    1. 概念 "发布(Publish)"一个对象:使对象能够在当前作用域之外的代码中使用. 例如:将一个指向该对象的引用保到其他代码可以访问的地方,或者在某个非私有的方法中返回该引用 ...

  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. SpringSecurity-eclipse
  2. 保姆级教程:Spring Boot 单元测试
  3. 第一弹:超全Python学习资源整理(入门系列)
  4. usb管控软件_数据防泄密软件介绍
  5. opcua协议服务器端口号,opc ua服务器 数据配置
  6. 计算机二级等级考试模拟试题,2016年计算机二级考试office模拟试题
  7. flex 底部固定_小猿圈网站页面底部固定的方法
  8. python如何爬取图片到指定文件夹论文_基于Python的图片爬虫程序设计
  9. ffmpeg (三):ffmpeg结合SDL2.0解码音频流
  10. EasyRecovery用法进阶--高阶设置使用技巧
  11. Java获取微信用户昵称时昵称里有特殊符号导致插入数据库失败(解决方案)
  12. informix操作
  13. Android的读写文件权限
  14. 微信可以一键恢复好友吗?
  15. 嘴哥有料系列-can工具1:CAN诊断浅谈 + 如何用CAN工具进行诊断
  16. Python 实现三维姿态估计遮挡匹配预测
  17. Angular 4 Http
  18. 利用malloc函数分配二维数组
  19. python如何定义类_python中定义类
  20. PHP采集器querylist

热门文章

  1. 从哪里查看计算机日期格式,进记账宝,提示下图,检查了计算机日期格式为‘-’,换台电脑也是不行,是哪里原因...
  2. 联想 android电视,手机电视无线连 联想电视多屏互动详解
  3. FreeModbus从站源码解析(portserial.c)
  4. python 做交易软件下载_利用python下载股票交易数据
  5. 如何提高团队凝聚力和执行力?
  6. xcode8 解决打印台打印不出来东西
  7. 读Unsupervised NMT
  8. 离线安装OneNote for Windows 10
  9. 山东大学软件工程应用与实践——GMSSL开源库(二)——浅尝SM9
  10. 江苏自考 计算机网络 是委托,2019年4月江苏自考《计算机网络原理》课程考试题型及范围...