博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【java】知识系谱-基础篇-线程-发布、逸出
阅读量:6939 次
发布时间:2019-06-27

本文共 2601 字,大约阅读时间需要 8 分钟。

java并发编程实战的解释,不够详细,尤其this引用逸出让人理解有些费解,java并发编程实战里面的内容就直接拷贝过来

发布:使对象能够在当前作用域之外的代码中使用逸出:当某个不该被发布的对象被发布时,这种情况称为逸出发布内部状态将会破坏封装性,并使得程序难以维持不变性条件当某个对象逸出后,必须对程序进行分析,以便找出哪些对象或线程可能会误用该对象,这正是使用封装的最主要原因:使对程序的正确性分析变为可能,并使无意中破坏设计约束条件变得更难无论其它的线程会对逸出的对象引用执行何种操作,都不重要,因为误用该引用的风险始终是客观存在的

发布的实现方式

1.对象引用作为非私有属性

代码示例:

//只是代码示例,不推荐这样初始化Listpublic class test {    public List
animals = new ArrayList
(){
{ add(new Animal()); }};}

List对象和List中的Animal对象都被发布出去。

2.对象引用被非私有方法返回

代码示例:

//只是代码示例,不推荐这样初始化Listpublic class test {    private List
animals = new ArrayList
(){
{ add(new Animal()); }}; public List
getAnimals(){ return animals; }}

1、2的一样,List对象和List中的Animal对象发布出去。只是一个是方法发布出去,一个是属性发布出去。

3.外部方法发布对象

外部方法定义:对当前类来说,外部方法是指行为不完全由当前类来规定的方法,包括其他类中定义的方法以及当前类中可以被改写的方法(既不是私有方法,也不是final方法)

代码示例:

public class test {    public void setAnimals(Animal animal){        animal.setDag(            new Dog(){                public void doSomething(){                     ...                };            }        )    }}

当前类test来说,setDag为外部方法,Dog就被发布了。

this引用逸出

基于外部方法发布对象引出this引用逸出问题。直接拿java并发编程实战的代码

public class ThisEscape {    public ThisEscape(EventSource source){        source.registerListener(            new EventListener(){                public void onEvent(Event e){                    doSomething(e)                }            });    }}java并发编程实战的解释:当ThisEscape发布EventListener时,它也无条件地发布了封装(enclosing)ThisEscape的实例,因为内引类(inner class inst ances)的实例包含了对封装实例隐含的引用。

这里发布new EventListener()内部对象,隐式的有个this。也就是ThisEscape也会被发布出去,但是ThisEscape还没有构建完成,存在逸出的可能,ThisEscape在未构建完成被发布了。怎么处理这个可能逸出的问题,就是让ThisEscape构建完成再发布出去就可以了。java并发编程实战的提到私有构造函数+公共的工厂方法解决可能逸出的问题。

public class ThisEscape {    private final EventListener listener;        private ThisEscape(){        listener = new EventListener(){            public void onEvent(Event e){                doSomething(e)            }        };    }        public static ThisEscape newInstance(EventSource source){        ThisEscape thisEscape = new ThisEscape();        source.registerListener(thisEscape.listener);        return thisEscape;    }    }

同理在构造函数可以新建线程,当不要start()。start()的话this被新线程共享。下面代码就是错误的:

public class ThisEscape {      private Thread thread;      public ThisEscape(){            thread = new Thread(){              public void run(){                     ...            }          };          thread.start(); //可以在构造函数中new Thread 但是不要start    }            public static void main(String[] args){          ThisEscape a = new ThisEscape();      }  }

转载地址:http://iusnl.baihongyu.com/

你可能感兴趣的文章
编程之美:寻找发帖"水王"
查看>>
eclips的一些快捷设置
查看>>
POJ 1769 Minimizing maximizer 线段树优化DP
查看>>
mvc 验证封装到某个特征类里[特性的使用]
查看>>
Redis配置文件详解
查看>>
SQL Mon 介绍
查看>>
yii2 对字段 自动加一 或 减一
查看>>
nginx负载均衡分配策略有哪些?
查看>>
localStorage
查看>>
简单的Asp.net mvc 里动态生成Linq的Ef查询扩展
查看>>
java.lang.reflect.InvocationTargetException
查看>>
完善(用户调研反馈+自评+典型用户与场景)
查看>>
elasticsearch接口开发(新)
查看>>
How to configure your MyInbox webpart automatically ?
查看>>
Linux : centOS 与 Ubuntu 安装 Nginx
查看>>
Django&Admin站点&调整站点信息
查看>>
POJ2125 Destroying The Graph
查看>>
详细的App推广前的准备工作
查看>>
15年1月的每天小程序
查看>>
多选插件multiselect.js
查看>>