在设计线程安全类的过程中,需要包含以下三个基本要素:
- ·找出构成对象状态的所有变量
- 找出约束变量的不变性条件
- 建立对象状态的并发访问管理策略
示例1: 使用Java监视器模式的线程安全计数器
@ThreadSafe public class Counter { @GuardedBy("this") private long value=0; public synchronized long getValue() { return value; } public synchronized long increment() { if(value==Long.MAX_VALUE) throw new IllegalStateException("Counter overflow"); return ++value; } }
实例封闭
将数据封装在对象内部,可以将数据的访问限制在对象的方法上,从而更容易确保线程在访问数据时总能持有正确的锁。
被封闭对象一定不能超出它们既定的作用域。对象可以封闭在类的一个实例(例如作为类的一个私有成员)中,或者封闭在某个作用域内(例如作为一个局部变量),再或者封闭在线程内(例如在某个线程中将对象从一个方法传递到另一个方法,而不是在多个线程之间共享该对象)。
示例二: 通过封闭机制来确保线程安全
@ThreadSafe public class PersonSet { @GuardedBy("this") private final Set<Person> mySet=new HashSet<Person>(); public synchronized void addPerson(Person p) { mySet.add(p); } public synchronized boolean containPerson(Person p) { return mySet.contains(p); } }