摘要:引用逸出基于外部方法发布对象引出引用逸出问题。并发编程实战的提到私有构造函数公共的工厂方法解决可能逸出的问题。同理在构造函数可以新建线程,当不要。下面代码就是错误的可以在构造函数中但是不要
java并发编程实战的解释,不够详细,尤其this引用逸出让人理解有些费解,java并发编程实战里面的内容就直接拷贝过来
发布:使对象能够在当前作用域之外的代码中使用 逸出:当某个不该被发布的对象被发布时,这种情况称为逸出 发布内部状态将会破坏封装性,并使得程序难以维持不变性条件 当某个对象逸出后,必须对程序进行分析,以便找出哪些对象或线程可能会误用该对象,这正是使用封装的最主要原因:使对程序的正确性分析变为可能,并使无意中破坏设计约束条件变得更难 无论其它的线程会对逸出的对象引用执行何种操作,都不重要,因为误用该引用的风险始终是客观存在的发布的实现方式 1.对象引用作为非私有属性
代码示例:
//只是代码示例,不推荐这样初始化List public class test { public Listanimals = new ArrayList (){{ add(new Animal()); }}; }
List对象和List中的Animal对象都被发布出去。
2.对象引用被非私有方法返回代码示例:
//只是代码示例,不推荐这样初始化List public class test { private Listanimals = 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(); } }
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/69062.html
摘要:每个会缓存主存的共享变量,从而提高处理效率。为当前缓存行加入缓存一致性协议。任何修改,其他线程是可见的。修饰的变量还是会缓存的,只是通过一系列处理保证了所有线程看到这个变量的值是一致的 java并发编程实战对volatile的解释就是:当一个域声明为valatile类型后,编译器与运行时会监视这个变量:它是共享的,而且对它的操作不会与其他的内存操作一起被重排序。volatile变量不会...
摘要:是需要我们去处理很多事情,为了防止多线程给我们带来的安全和性能的问题下面就来简单总结一下我们需要哪些知识点来解决多线程遇到的问题。 前言 不小心就鸽了几天没有更新了,这个星期回家咯。在学校的日子要努力一点才行! 只有光头才能变强 回顾前面: 多线程三分钟就可以入个门了! Thread源码剖析 本文章的知识主要参考《Java并发编程实战》这本书的前4章,这本书的前4章都是讲解并发的基...
摘要:发布的对象内部状态可能会破坏封装性,使程序难以维持不变性条件。不变性线程安全性是不可变对象的固有属性之一。可变对象必须通过安全方式来发布,并且必须是线程安全的或者有某个锁保护起来。 线程的优缺点 线程是系统调度的基本单位。线程如果使用得当,可以有效地降低程序的开发和维护等成本,同时提升复杂应用程序的性能。多线程程序可以通过提高处理器资源的利用率来提升系统的吞吐率。与此同时,在线程的使用...
摘要:对象的共享上一章介绍了如何通过同步来避免多个线程在同一时刻访问相同的数据,而本章将介绍如何共享和发布对象,从而使它们能够安全地由多个线程同时访问。为了确保多个线程的之间对内存写入操作的可见性,必须使用同步机制。 对象的共享 上一章介绍了如何通过同步来避免多个线程在同一时刻访问相同的数据,而本章将介绍如何共享和发布对象,从而使它们能够安全地由多个线程同时访问。 列同步代码块和同步方法可...
摘要:当某个不应该发布的对象被发布时,这种情况被称为逸出。线程安全共享线程安全的对象在其内部实现同步,因此多线程可以通过对象的公有接口来进行访问而不需要进一步的同步。 前言 本系列博客是对《Java并发编程实战》的一点总结,本篇主要讲解以下几个内容,内容会比较枯燥。可能大家看标题不能能直观的感受出到底什么意思,这就是专业术语,哈哈,解释下,术语(terminology)是在特定学科领域用...
阅读 803·2021-09-22 15:18
阅读 1151·2021-09-09 09:33
阅读 2733·2019-08-30 10:56
阅读 1152·2019-08-29 16:30
阅读 1448·2019-08-29 13:02
阅读 1430·2019-08-26 13:55
阅读 1613·2019-08-26 13:41
阅读 1904·2019-08-26 11:56