Java并发编程(十一)实例封闭

本节主题:如果一个类是线程不安全的,但是又要在多线程程序中安全地使用,你该怎么办?

大体有两种思路:

第一种:确保该对象是能由单个线程访问,也就是这个对象是被封闭在线程中的;

第二种:通过锁来对该对象的访问进行保护。

实例封闭

封装简化了线程安全类的实现过程,提供了一种实例封闭机制(Instance Confinement)。

当一个对象被封装到另一个对象中时,能够访问被封装对象的所有的代码路径都是已知的,与不安全的类散落在整个程序中相比,更加易于分析。通过将封闭机制与合适的加锁策略结合起来,可以确保线程安全的方式来使用非线程安全的对象。

被封闭的对象一定不能超过既有的作用域,对象可以封闭在类的一个实例(作为私有成员);

或者封闭在某个作用域内(例如作为一个局部变量),再或者封闭在线程内(一个方法传到另一个方法中,而不是在多个线程中共享该对象)。

要注意,对象本身不会在发布的时候逸出。

私有一个对象;

控制该对象的访问路径;

加上适当的锁机制。

实例封闭是构建线程安全类的一个最简单的方式,它还使得在锁策略的选择上有了更多的灵活性。实例封闭可以使得不同的状态变量由不同的锁来保护,而其他形式的锁需要自始至终都用同一个锁。

Collections.synchronizedListy及其类似的方法,使得非线程安全的类可以在多线程环境中使用。这些工厂方法通过装饰器模式将容器类封装在一个同步的包装器对象中,而包装器对象能将接口中的每个方法都实现为同步方法,并将调用请求转发到底层的容器对象上。只要包装器对象拥有对底层容器对象的唯一引用(即把底层容器对象封闭在包装器中),那么它就是线程安全的。

Java监视器模式

Java监视器模式的对象会把对象的所有可变状态封装起来,并由对象自己的内置锁来保护。

使用私有锁对象而不是对象的内置锁(或其他任何可以通过共有方式访问的锁),有许多优点。私有的锁对象可以将锁封装起来,使客户端无法得到锁。

原文地址:https://www.cnblogs.com/tuhooo/p/8036604.html