Java并发编程(二) 创建线程安全的类

1. 线程安全的类

  多线程环境中访问某个类时,不需要额外的同步或者协同,这个类都能表现出正确的行为,则称该类是线程安全的。

 

2. 设计线程安全的类的基本步骤:

 (1)找出构成对象所有状态的域

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

 (3)设计对象状态的并发访问和管理策略

 收集同步需求:我们需要分析对象的不变性条件,在执行某个操作时,需要判断操作执行之后是否会导致对象的状态违反了这些不变性条件,如果违反则不执行操作。

  例如:对象中有一个温度的属性,规定了一个温度的合理值范围是10~20度,则若某个操作试图修改温度的值为30,则违反了不变性条件。

 依赖当前状态的操作:如果执行某个操作需要依赖对象当前的状态,还可能要求当前对象的状态满足一些先验条件才能执行操作。

  例如:队列当前状态为空,则出队操作不能执行。 单线程环境中操作遇到条件不满足时通常就失败,但在多线程环境中,操作失败时可以阻塞当前线程等待其他线程改变状态到条件满足,可以使用notify方法和wait方法。

  保持对象的所有权:Java类库中的容器类通常表现出“所有权”分离的形式,容器类有自身的状态,容器中的对象有自己本身的状态。我们在设计自己的线程安全类时也要尽量做到这一点,不要使对象逸出。

 

3. 实例封闭

  如果某个对象不是线程安全的,可以通过封装的机制,将该对象封装在另一个对象中,然后提供一些同步方法来确保对底层对象的同步访问。

  Java类库中有大量的实例封闭的例子,如:Collections.synchronizedList、Collections.synchronizedSet等方法可以实现将非线程安全的类对象封装到同步之后的集合类对象中。

 

4. 线程安全性的委托

  如果类的组件已经是线程安全的,那么我们就可以将类的线程安全性委托给组件的线程安全性。

  需要注意的是,如果类中有多个线程安全的组件,那么需要注意这些组件之间是否是独立的,如果他们是彼此独立的,那么我们也可以将类的线程安全性委托给这些组件而不需要额外增加一些约束;但如果类的各个组件之间还有一些约束关系,那我们就需要在类中添加额外的加锁机制来实现操作的线程安全性。

 

 

 

参考资料 《Java并发编程实战》

posted @ 2015-09-01 10:55  jqc  阅读(695)  评论(0编辑  收藏  举报