文章目录

  • 脑图
  • 概念
  • 示例
    • 不安全的发布对象Demo
    • 对象逸出Demo
  • 小结
  • 代码

脑图


概念

发布对象: 使一个对象能够被当前范围之外的代码所使用,日常开发中比较常见的比如通过类的非私有方法返回对象的引用,或者通过公有的静态变量发布对象 等都属于发布对象

对象逸出: 首先需要明确的是对象逸出是一种错误的发布方式当一个对象还没有构造完成时,就使它被其他线程所见


示例

不安全的发布对象Demo

package com.artisan.example.publish;import com.artisan.anno.NotThreadSafe;import lombok.extern.slf4j.Slf4j;@Slf4j
@NotThreadSafe
public class UnSafePublishObjectDemo {// 私有变量private String name = "artisan";// 通过public访问级别的方法getName发布了类的域,在类的外部,任何线程都可以访问这个域// 这样发布的对象是不安全的,因为我们无法得知其他线程是否会修改这个域导致该类里数据的错误public String  getName() {return name;}public static void main(String[] args) {// 通过new实例化UnSafePublishObjectDemoUnSafePublishObjectDemo unSafePublishObjectDemo = new UnSafePublishObjectDemo();// 调用getName()方法得到私有属性的引用String name = unSafePublishObjectDemo.getName();log.info("name:{}",name);// 假设有第二个线程去修改name属性的值String name2 = unSafePublishObjectDemo.getName();name2 = "小工匠";log.info("name:{}",name2);}}

上面的代码里,通过new对象初始化了UnSafePublishObjectDemo对象。然后调用getName()方法获取到了私有属性的引用,这样就可以在其他任何线程中,修改该属性的值。这样将会导致我们在其他线程中,获取该属性的值时是不确定的,因为并不能得知该属性的值是否已被其他线程所修改过,所以这就是不安全的对象发布。


对象逸出Demo

package com.artisan.example.publish;import com.artisan.anno.NotRecommand;
import com.artisan.anno.NotThreadSafe;import lombok.extern.slf4j.Slf4j;/*** *  对象逸出示例,在对象构造完成之前,不可以将其发布* @author yangshangwei**/
@Slf4j
@NotThreadSafe
@NotRecommand
public class ObjectEscapeDemo {private int thisCanBeEscape = 0;public ObjectEscapeDemo() {new InnerClass();}private class InnerClass {// this引用的逸出// 内部类的构造器里包含了对封装实例的隐含引用,这样在对象没有被正确构造完成之前就会被发布,由此会导致不安全的因素在里面public InnerClass() {log.info("{}", ObjectEscapeDemo.this.thisCanBeEscape);}}public static void main(String[] args) {new ObjectEscapeDemo();}}

上述代码中,内部类的构造器里包含了对封装实例的隐含引用,这样在对象没有被正确构造完成之前就会被发布,由此会导致不安全的因素在里面。

其中一个就是导致this引用在构造期间逸出的错误,它是在构造函数构造过程中启动了一个线程,无论是显式启动还是隐式启动,都会造成this引用的逸出

新线程总会在所属对象构造完毕之前就已经看到它了,所以如果要在构造函数中创建线程,那么不要启动它,而是应该采用一个专有的start,或是其他初始化的方式统一启动线程。

这里其实我们可以使用工厂方法和私有构造函数来完成对象创建和监听器的注册等等来避免不正确的发布。


小结

不正确的发布可变对象导致的两种错误:

  • 发布线程以外的所有线程都可以看到被发布对象的过期的值
  • 线程看到的被发布对象的引用是最新的,然而被发布对象的状态却是过期的

代码

https://github.com/yangshangwei/ConcurrencyMaster

并发编程-08安全发布对象之发布与逸出相关推荐

  1. Java 并发编程(二)对象的发布逸出和线程封闭

    对象的发布与逸出 "发布(Publish)"一个对象是指使对象能够在当前作用域之外的代码中使用.可以通过 公有静态变量,非私有方法,构造方法内隐含引用 三种方式. 如果对象构造完成 ...

  2. 从头认识多线程-4.1 对象的发布(Publish)、逸出(Escape)以及逸出的解决方案

    这一章节我们来讨论一下对象的发布与逸出. 其实在前两个章节我们都有想应的讨论,只不过有一些不用补充的问题,我将会放到这个章节里面去. 1.发布(Publish) 当一个对象能够给其他代码引用. pac ...

  3. java单线程共享,「Java并发编程实战」之对象的共享

    前言 本系列博客是对<Java并发编程实战>的一点总结,本篇主要讲解以下几个内容,内容会比较枯燥.可能大家看标题不能能直观的感受出到底什么意思,这就是专业术语,哈哈,解释下,术语(term ...

  4. 【Java并发编程实战】03对象的共享

    上一篇介绍了如何通过同步多个线程避免同一时刻访问相同数据,本篇介绍如何共享和发布对象,使它们被安全地由多个进程访问. 1.可见性 通常,我们无法保证执行读操作的线程能看到其他线程写入的值,因为每个线程 ...

  5. Java并发编程(08):Executor线程池框架

    本文源码:GitHub·点这里 || GitEE·点这里 一.Executor框架简介 1.基础简介 Executor系统中,将线程任务提交和任务执行进行了解耦的设计,Executor有各种功能强大的 ...

  6. java对象不会被改变_Java 并发编程(二)对象的不变性和安全的公布对象

    二.安全公布 到眼下为止,我们重点讨论的是怎样确保对象不被公布,比如让对象封闭在线程或还有一个对象的内部.当然,在某些情况下我们希望在多个线程间共享对象,此时必须确保安全地进行共享.然而,假设仅仅是像 ...

  7. 【多线程】java 并发编程中的Condition对象-指定唤醒某个线程

    1.概述 转载:java高并发系列 - 第13天:JUC中的Condition对象 synchronized中实现线程等待和唤醒 Condition简介及常用方法介绍及相关示例 使用Condition ...

  8. 实战并发编程 - 08基于Guarded Suspension模式优化轮询while(true)

    文章目录 Guarded Suspension模式简介 看牙医的就诊流程 代码举例 总结与拓展 Guarded Suspension模式简介 guarded在这里是"保护"的意思: ...

  9. java并发进程共享变量_JAVA并发编程学习:共享对象

    可见性 在一个单线程程序中,如果向一个变量先写入值,然后在没有写干涉的情况下读取这个变量,会得到相同的返回值.但是当读和写发生在不同的线程中时,就不能保证读线程及时地读取其他线程写入的值.在JAVA中 ...

最新文章

  1. 服务器log文件清理,服务器日志切割清理工具(LogCutter)
  2. springboot 按钮权限验证_SpringBoot中实现Shiro控制ThymeLeaf界面按钮级权限控制
  3. 这是一个无效的源路径
  4. js json制表符报错_JS自学_常见错误复盘
  5. .NET单点登录实现方法----两种
  6. 定义一个没有参数的函数、输出python3次_Python函数参数详解,三天让你掌握python,不再是小白
  7. Python matplotlib生成图片背景透明
  8. oracle--Tracing PL/SQL subprogram calls with parameters values--Mahmoud Hatem,
  9. 将本地电脑文件复制到虚拟机系统中详细方法
  10. 戴尔服务器显示器接口类型,拒绝凌乱桌面 Type-C接口显示器的魅力
  11. 软件工程之图书管理系统总体设计
  12. 计算机绘图 cad),CAD计算机绘图入门
  13. 【打印机】mac上添加打印机
  14. 批量将多张图片的宽度和高度同时缩小一半,也可以按固定比例缩小
  15. nagios详细解说
  16. java jni dll路径_Java中Jni调用DLL文件试验
  17. 《Fluid Engine Development》 学习笔记2-基础
  18. java并发编程实战wwj----------------------第二阶段-------不可变对象-------19-20
  19. 机器学习入门0005 tensorflow_NMT模型
  20. 计算机学院毕业条幅,欢送毕业生横幅标语

热门文章

  1. python list 去重_Python中对列表list去重
  2. c++ 使用对象指针
  3. xgboost 的 get_fscore()
  4. wps 项目进度_平安科技软件+金山WPS测试面试题
  5. 廖的python教程_学廖老师的python教程想到的
  6. MAC电脑快捷键整理
  7. 从C语言的角度重构数据结构系列(二)-如何衡量一个算法的优劣?
  8. tableau实战系列(九)-用 ZN 函数处理数据缺失点
  9. 长安大学微型计算机原理与接口技术答案,长安大学微机原理与接口技术A卷答案...
  10. 《京东技术解密》——海量订单处理