Java并发编程(五):Java线程安全性中的对象发布和逸出
发布(Publish)和逸出(Escape)这两个概念倒是第一次听说,不过它在实际当中却十分常见,这和Java并发编程的线程安全性就很大的关系。
什么是发布?简单来说就是提供一个对象的引用给作用域之外的代码。比如return一个对象,或者作为参数传递到其他类的方法中。
什么是逸出?如果一个类还没有构造结束就已经提供给了外部代码一个对象引用即发布了该对象,此时叫做对象逸出,对象的逸出会破坏线程的安全性。
概念我们知道了,可我们要关注什么地方呢?我们要关注的时候就是逸出问题,在不该发布该对象的地方就不要发布该对象,例如以下代码:

1 class UnsafeStates{
2 private String[] states = new String[]{"AK", "AL"};
3
4 public String[] getStates(){
5 return states;
6 }
7 }

states变量作用域是private而我们在getStates方法中却把它发布了,这样就称为数组states逸出了它所在的作用域。
然而更加隐蔽和需要我们注意的是this逸出,这个问题要引起重点关注。什么是this逸出?观察以下代码:

1 public class ThisEscape{
2 private int value;
3 public ThisEscape(EventSource source){
4 source.registerListener{
5 new EventListener(){
6 public void onEvent(Event e){
7 doSomething(e);
8 }
9 }
10 }
11 //一些初始化工作
12 value = 7;
13 }
14
15 public void doSomething(Event e){
16 System.out.println(value);
17 }
18
19 }

在构造方法中我们定义了一个匿名内部类,匿名内部类是一个事件监听类,当事件监听类注册完毕后,实际上我们已经将EventListener匿名内部类发布出去了,而此时我们实际上已经携带了this逸出,重点在于这个时候我们还有一些初始化工作没有做完(代码11行之后),这也就是上面所说的,一个类还没有构造结束我们已经将发布了。那怎么来避免this逸出呢?既然我们没有构造完构造函数,那我们就将构造函数构造完嘛,将构造函数定义为private作用域。如以下代码所示:

1 public class SafeListener{
2 private final EventListener listener;
3
4 private safeListener(){
5 listener = new EventListener(){
6 public void onEvent(Event e){
7 doSomething(e);
8 }
9 }
10 }
11
12 public static SafeListener newInstance(EventSource source){
13 SafeListener safeListener = new SafeListener();
14 safeListener.registerListener(safeListener.listener);
15
16 return safeListener;
17 }
18 }

我们首先将构造函数设定为private,其次我们在构造函数未完成时不将对象进行发布,而是使用工厂方法,在工厂方法newInstance中待构造函数执行完毕后再将对象进行发布(代码中即为registenerListener注册监听)。这实际上就是修改为了构造完毕->发布对象的串行执行模式,而不是之前的异步模式,这样就不会给我们带来线程安全性的问题。
Java并发编程(五):Java线程安全性中的对象发布和逸出的更多相关文章
- Java线程安全性中的对象发布和逸出
发布(Publish)和逸出(Escape)这两个概念倒是第一次听说,不过它在实际当中却十分常见,这和Java并发编程的线程安全性就很大的关系. 什么是发布?简单来说就是提供一个对象的引用给作用域之外 ...
- 【Java并发编程一】线程安全和共享对象
一.什么是线程安全 当多个线程访问一个类时,如果不用考虑这些线程在运行时环境下的调度和交替执行,并且不需要额外的同步及在调用代码代码不必作其他的协调,这个类的行为仍然是正确的,那么称这个类是线程安全的 ...
- java并发编程实战之线程安全性(一)
1.1什么是线程安全性 要对线程安全性给出一个确切的定义是非常复杂的.最核心的概念就是正确性.正确性:某个类的行为与其规范完全一致.在良好的规范中通常会定义各种不变性条件来约束对象的状态,以及定义各种 ...
- Java并发编程实战 之 线程安全性
1.什么是线程安全性 当多个线程访问某个类时,不管运行时环境采用何种调用方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全 ...
- Java并发编程 (五) 线程安全性
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.安全发布对象-发布与逸出 1.发布与逸出定义 发布对象 : 使一个对象能够被当前范围之外的代码所使用 ...
- Java并发编程系列-(2) 线程的并发工具类
2.线程的并发工具类 2.1 Fork-Join JDK 7中引入了fork-join框架,专门来解决计算密集型的任务.可以将一个大任务,拆分成若干个小任务,如下图所示: Fork-Join框架利用了 ...
- Java并发编程:Java的四种线程池的使用,以及自定义线程工厂
目录 引言 四种线程池 newCachedThreadPool:可缓存的线程池 newFixedThreadPool:定长线程池 newSingleThreadExecutor:单线程线程池 newS ...
- 【java并发编程实战】-----线程基本概念
学习Java并发已经有一个多月了,感觉有些东西学习一会儿了就会忘记,做了一些笔记但是不系统,对于Java并发这么大的"系统",需要自己好好总结.整理才能征服它.希望同仁们一起来学习 ...
- 【Java并发编程六】线程池
一.概述 在执行并发任务时,我们可以把任务传递给一个线程池,来替代为每个并发执行的任务都启动一个新的线程,只要池里有空闲的线程,任务就会分配一个线程执行.在线程池的内部,任务被插入一个阻塞队列(Blo ...
随机推荐
- 搭建maven支持的web工程的步骤
搭建一个新的web project的整体思路:先用maven搭建项目的骨架,生成mvn project,然后将mvn project转换为web project,最后添加相关的Spring,hiber ...
- Web安全开发指南--会话管理
1.会话管理 3.1.会话管理安全规则 1 避免在URL携带session id. 2 使用SSL加密通道来传输cookie. 3 避免在错误信息和调试日志中记录session id. 4 使用框架自 ...
- 详解MySQL性能优化(二)
http://www.jb51.net/article/70530.htm 七.MySQL数据库Schema设计的性能优化高效的模型设计 适度冗余-让Query尽两减少Join 大字段垂直分拆-sum ...
- how to solve "[WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent!"
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
- 使用tcp.validnode_checking允许、限制机器访问数据库
使用tcp.validnode_checking允许.限制机器访问数据库 在$OREACLE_HOME/network/admin下直接修改sqlnet.ora文件,增加如下内容: tcp. ...
- JAVA常见算法题(二十八)
package com.forezp.util; import java.util.Arrays; /** * 两个int数组,都是从小到大的的排列,请合并为一个新的数组,也是从小到到大的排列, * ...
- --secure-file-priv option so it cannot execute this statement
MYSQL导入数据出现The MySQL server is running with the --secure-file-priv option so it cannot execute this ...
- go语言基础之iota枚举
1.iota (在常量的时候,当成枚举使用) 示例1 package main import "fmt" func main() { //1.iota常量自动生成器,每个一行,自动 ...
- phpcms的后台网站直接访问正常,百度快照收录链接访问跳转到非法网站
问题: phpcms制作的网站直接访问正常,百度快照收录链接访问跳转到非法网站 百度快照收录网站域名,访问时自动跳转到一个非法网站 检查静态页index.html,index.php 网页内引用 ...
- Java实现文件MD5加密
代码实现: import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.s ...