JAVA并发编程实战——对象组合

来源:互联网 发布:世界地图 销售网络 编辑:程序博客网 时间:2024/06/16 09:31

4.1 设计线程安全的类
在设计线程安全类的过程中,需要包含以下三个基本要素:
1.找出构成对象状态的所有变量。
2.找出约束状态变量的不变性条件(找出这些条件,然后对这些条件进行并发策略管理,使其线程安全)
3.建立对象状态的并发访问管理策略。
以上三条理解为:先找出所有具有不变性条件的变量,然后确定这些变量的不变性条件是什么,再对这些不变性条件进行并发访问策略管理(就是同步)就能设计线程安全的类。
4.1.1:收集同步需求。
确保类的线程安全,就需要确保它的不变性条件不会在并发访问的情况下破坏。
4.1.2:依赖状态的操作
某个操作中包含有基于状态的先验条件,那么这个操作就称为依赖状态的操作。
例如,对一个队列进行操作,在删除元素的时候,队列必须处于“非空”的状态。在并发的情况下,很就有可能当你准备删除的时候,队列不为空,但其它线程可能会导致这种状态发生改变。将队列变为了空。这个也就是先验条件。
不变性条件:比如一个Integer对象,最大值就是整数的最大值,这个就是他的不可变性。如果对其进行加法操作。并发情况下,就可能导致不可变性发生。是的对象的状态无效。
后验条件:比如对一个Integer对象进行i++;那么如果当前的值为19,那么它的下一个值一定为20.当你获取的时候,在并发下,那么你可能当前值为19.下次获取确实不是20.这就是后验条件导致对象状态迁移无效。就是下一个状态需要依赖当前状态时。需要进行并发处理。

4.2 实例封闭
如果某个对象不是线程安全的,可以通过实例封闭的方法使其线程安全 实例封闭(将对象作为类的一个私有成员) 也可以封闭在某个作用域(作为一个局部变量), 线程封闭(对象在某一个线程中传递)

public class PersonSet {    private final Set<Person> mySet = new HashSet<Person>();    public synchronized void addPerson(Person p) {          mySet.add(p);    }    public synchronized boolean containsPerson(Person p ) {        return  mySet.contains(p);    }}

例中的PersonSet 的状态变量是HashSet集合。 但是HashSet线程不安全。但是我们将HashSet封闭成类的一个私有成员。并将访问HashSet集合的路径(add方法和contains方法)都进行加锁。这样PersonSet这个类就线程安全了。

4.2.1 Java监视器模式:每个java对象都可以做一个实现同步的锁,这些锁被称为内置锁(Intrinsic Lock)或监视器锁(Monitor Lock)
java监视器模式仅仅是一种代码约定,对于某个类的域变量,如果能够自始至终都使用同一种锁对象保护的同步代码来访问,则代码即为遵循java监视器模式的

public class PersonSet {     private Integer age;    public  synchronized Integer getAge() {        return age;    }    public synchronized  void setAge(Integer age) {        this.age = age;    }}
0 0