设计线程安全的类要包括三个基本要素: .)找出构成对象状态的全部变量; .)找出约束状态变量的不变性条件; .)创建对象状态并发访问管理策略。安全
一、实例封闭(使用内置锁保护访问方法)并发
public class PersonSet { @GuardedBy("this") final Set<Person> mySet = new HashSet<Person>(); public synchronized void addPerson(Person p){ mySet.add(p); Collections.synchronizedList(new ArrayList<String>()); //SynchronizedList装饰器模式 } public synchronized Set<Person> getSet(){ return mySet; } static class Person { } }
二、监视器模式(使用私有的锁而不是内置锁)this
public class PrivateLock { private final Object myLock = new Object(); @GuardedBy("myLock") Widget widget; void someMethod(){ synchronized(myLock){ //TODO } } }
私有锁的优势(不用内置锁不用其余能够经过公有方式访问的锁): .)私有锁对象可能将锁封装起来,客户端没法获得锁,只能经过公有方法访问锁; .)公共访问的锁是否被正确使用须要检查整个程序。线程
3.线程安全性的委托 .)单个状态变量的集合委托给线程安全的集合; .)相互独立的多个状态变量,即多个状态变量之间不会引入不变性条件; .)发布线程安全的状态。设计
四、现有的线程安全类中添加功能 .)扩展方法比直接添加代码到类中更加脆弱,会改变同步策略; .)客户端加锁机制:使用某个对象X的客户端代码,使用X自己用于保护状态的锁来保护这段代码,必须知道对象X使用的是哪个锁,缺点是派生类的行为与基类的实现耦合在一块儿,破坏同步策略的封装性; .)组合(Composition)是最合适的,装饰器模式。code