1.找出构成对象状态的全部变量; java
2.找出约束状态变量的不变性条件; 安全
3.创建对象状态的并发访问管理策略。 并发
/** * 这里将mySet实例封闭在PersonSet中, * 尽管HashSet是非线程安全类, * 因为mySet是私有且不会逸出的, * 咱们经过公共接口提供给外部访问,但加上了PersonSet内置锁保护synchronized, * 于是PersonSet是一个线程安全的类 */ @ThreadSafe public class PersonSet { private final Set<Person> mySet = new HashSet<>(); public synchronized void addPerson(Person p){ mySet.add(p); } public synchronized boolean containsPerson(Person p){ return mySet.contains(p); } }
public class PrivateLock { private final Object lock = new Object(); public void methodOne(){ synchronized(lock){ // do sth. } } }
/** * 委托的PersonSet * 将内部操做委托给线程安全的类SynchronizedSet * 从而自身也是线程安全的 */ @ThreadSafe public class DelegatingPersonSet { private final Set<Person> mySet = Collections.synchronizedSet(new HashSet<Person>()); public void addPerson(Person p){ mySet.add(p); } public boolean containsPerson(Person p){ return mySet.contains(p); } }
/** * 将线程安全性委托给多个彼此独立的状态变量 * VisualComponent使用CopyOnWriteArrayList(线程安全)来保存监听器列表 * keyListeners, mouseListeners彼此独立 * 所以VisualComponent线程安全 */ public class VisualComponent { private final List<KeyListener> keyListeners = new CopyOnWriteArrayList<>(); private final List<MouseListener> mouseListeners = new CopyOnWriteArrayList<>(); public void addKeyListener(KeyListener keyListener){ keyListeners.add(keyListener); } public void removeKeyListener(KeyListener keyListener){ keyListeners.remove(keyListener); } public void addMouseListener(MouseListener mouseListener){ mouseListeners.add(mouseListener); } public void removeMouseListener(MouseListener mouseListener){ mouseListeners.remove(mouseListener); } }
/** * NumberRange不足以保护它的不变性条件 * 并发环境下不安全 */ @NotThreadSafe public class NumberRange { //不变性条件: lower <= upper private final AtomicInteger lower = new AtomicInteger(); private final AtomicInteger upper = new AtomicInteger(); public void setLower(int i){ if (i > upper.get()){ //不安全的检查 throw new IllegalArgumentException("lower can't > upper"); } lower.set(i); } public void setUpper(int i){ if (i < lower.get()){ //不安全的检查 throw new IllegalArgumentException("lower can't > upper"); } upper.set(i); } }
/** * 经过扩展实现非重复Vector */ public class NoRepeatVector<E> extends Vector<E> { public synchronized boolean putIfAbsent(E e){ boolean exist = contains(e); if (!exist) add(e); return exist; } }
/** * 这段客户端代码看似线程安全, * 但其实并不安全,由于锁住的对象不正确, * 这里仅是锁住ListHelper对象,但list对象并无被锁住, * 其余客户端仍可在不安全状况下对list进行操做 */ @NotThreadSafe public class ListHelper<E> { public List<E> list = Collections.synchronizedList(new ArrayList<E>()); public synchronized boolean putIfAbsent(E x){ boolean absent = !list.contains(x); if (absent) list.add(x); return absent; } }因此上面的代码,咱们应该对list加锁,而不是ListHelper对象:
@ThreadSafe public class SafeListHelper<E> { public List<E> list = Collections.synchronizedList(new ArrayList<E>()); public boolean putIfAbsent(E x){ synchronized (list) { boolean absent = !list.contains(x); if (absent) list.add(x); return absent; } } }
/** * 经过组合实现"若没有则添加" 下午4:48:42 */ @ThreadSafe public class improvedList<T> implements List<T> { private final List<T> list; public improvedList(List<T> list) { this.list = list; } public synchronized boolean putIfAbsent(T t){ boolean absent = !list.contains(t); if (absent) list.add(t); return absent; } @Override public synchronized int size() { return list.size(); } ... }
不吝指正。 ide