第四章 对象的组合(一)

前言:本章将介绍一些组合模式,这些模式能够使一个类更容易设计成线程安全的,并且在维护这些类时不会无意中破坏类的安全性保证。


4.1 设计线程安全的类

    在设计线程安全的类过程中,需要包含以下三个基本要素:

(1)找出构成对象状态的所有变量。

(2)找出约束状态变量的不变性条件。

(3)建立对象状态的并发访问管理策略。


4.2 实例封闭

    将数据封装在对象内部,可以将数据的访问限制在对象的方法上,从而更容易确保线程在访问数据时总能持有正确的锁。

被封闭对象一定不能够超出它们既定的作用域。对象可以封闭在一个类的实例中(例如作为类的一个私有成员),或者封闭在某个作用域内(例如作为一个局部变量),再或者封闭在一个线程内。

程序清单4-2说明了如何通过封闭和加锁机制使一个类成为线程安全的。

4-2 通过封闭机制来确保线程安全

public class PersonSet{

     private final Set mySet = new HashSet<>();

     public synchronized void addPerson(Person p){

            mySet.add(p);

     }

     public synchronized boolean containsPerson(Person p){

           return mySet.contains(p);

     }

}

实例封闭是构建线程安全类的一个最简单方式。Java类库中还有很多线程封闭的实例,最典型的是一些将非线程安全的类转化为线程安全类的包装器类。例如(Collections.synchronizedList(List list))。


4.2.1 Java 监视器模式

从线程封闭原则及其逻辑推论可以得出Java 监视器模式。遵循Java 监视器模式的对象会把对象的所有可变状态封装起来,并由自己的内置锁来保护。(例如Vector 和 HashTable)

程序清单4-3 通过一个私有锁来保护状态

public class PivateLock{

       private final Object myLock = new Object();

       void someMethod(){

             synchronized(myLock){

             }

        }

}

使用私有的锁对象而不是对象的内置锁有许多优点。私有的锁对象可以将锁对象封装起来,使客户代码无法得到锁,但客户代码可以通过公有方法来访问锁,以便参与到它的同步策略中。

你可能感兴趣的:(第四章 对象的组合(一))