商城网站建设推广,网站推广 昆明,网站免费永久,网站模板建站教程视频对象的组合#xff1a;如何将现有的线程安全组件#xff0c;组合成我们想要的更大规模的程序。设计线程安全的类#xff1a;设计线程安全类的三个要素#xff1a;1.找出构成对象状态的所有变量#xff1b;2.找出约束状态变量的不变性条件#xff1b;3.建立对象状态的并发…对象的组合如何将现有的线程安全组件组合成我们想要的更大规模的程序。设计线程安全的类设计线程安全类的三个要素1.找出构成对象状态的所有变量2.找出约束状态变量的不变性条件3.建立对象状态的并发访问管理策略。收集同步需求如果不了解对象的不变性条件与后验条件那就不能确保线程安全性。要满足在状态变量的有效值或状态转换上的各种约束条件就需要借助原子性和封装性。依赖状态的操作如果在某个操作中包含有基于状态的先验条件那么这个操作就称为依赖状态的操作。如在操作前判断当前状态是否可以进行当前操作。状态的所有权所有权与封装性总是相互关联的对象封装它拥有的状态即对它封装的状态拥有所有权当然所有权可以通过传递对象变成共享所有权。实例封闭将数据封装在对象内部可以将数据的访问限制在对象的方法上从而更容易确保线程在访问数据时总能持有正确的锁。/*** 这里将mySet实例封闭在PersonSet中* 尽管HashSet是非线程安全类* 由于mySet是私有且不会逸出的,* 我们通过公共接口提供给外部访问但加上了PersonSet内置锁保护synchronized,* 因而PersonSet是一个线程安全的类*/ThreadSafepublic class PersonSet {private final Set mySet new HashSet();public synchronized void addPerson(Person p){mySet.add(p);}public synchronized boolean containsPerson(Person p){return mySet.contains(p);}}封闭机制更易于构造线程安全的类因为当封闭类的状态时在分析类的线程安全性时就无须检查整个程序。Java监视器模式Java监视器模式的对象会把对象的所有可变状态都封装起来并由对象自己的内置锁来保护。如Vector, Hashtable等类我们也可以通过私有锁来代替内置锁public class PrivateLock {private final Object lock new Object();public void methodOne(){synchronized(lock){// do sth.}}}线程安全性的委托多个线程安全的类组合成的类不一定就是线程安全的。/*** 委托的PersonSet* 将内部操作委托给线程安全的类SynchronizedSet* 从而自身也是线程安全的*/ThreadSafepublic class DelegatingPersonSet {private final Set mySet Collections.synchronizedSet(new HashSet());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 keyListeners new CopyOnWriteArrayList();private final List 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不足以保护它的不变性条件* 并发环境下不安全*/NotThreadSafepublic class NumberRange {//不变性条件: lower upperprivate final AtomicInteger lower new AtomicInteger();private final AtomicInteger upper new AtomicInteger();public void setLower(int i){if (i upper.get()){ //不安全的检查throw new IllegalArgumentException(lower cant upper);}lower.set(i);}public void setUpper(int i){if (i lower.get()){ //不安全的检查throw new IllegalArgumentException(lower cant upper);}upper.set(i);}}如果一个类是由多个独立且线程安全的状态变量组成并且在所有的操作中都不包含无效状态转换那么可以将线程安全性委托给底层的状态变量。发布底层的状态变量如果一个状态变量是线程安全的并且没有任何不变性条件来约束它的值在变量的操作上也不存在任何不允许的状态转换那么就可以安全地发布这个变量例如发布上面VisualComponent的keyListeners, mouseListeners。在现有的线程安全类中添加功能通过扩展类来添加功能。/*** 通过扩展实现非重复Vector*/public class NoRepeatVector extends Vector {public synchronized boolean putIfAbsent(E e){boolean exist contains(e);if (!exist)add(e);return exist;}}客户端加锁机制客户端加锁对于使用某个对象X的客户端代码使用X本身用于保护其状态的锁来保护这段客户端代码。/*** 这段客户端代码看似线程安全* 但其实并不安全因为锁住的对象不正确* 这里仅是锁住ListHelper对象但list对象并没有被锁住* 其他客户端仍可在不安全情况下对list进行操作*/NotThreadSafepublic class ListHelper {public List list Collections.synchronizedList(new ArrayList());public synchronized boolean putIfAbsent(E x){boolean absent !list.contains(x);if (absent)list.add(x);return absent;}} 所以上面的代码我们应该对list加锁而不是ListHelper对象ThreadSafepublic class SafeListHelper {public List list Collections.synchronizedList(new ArrayList());public boolean putIfAbsent(E x){synchronized (list) {boolean absent !list.contains(x);if (absent)list.add(x);return absent;}}}组合当为现有的类添加一个原子操作时有一种更好的方法组合(Composition)。/*** 通过组合实现若没有则添加 下午4:48:42*/ThreadSafepublic class improvedList implements List {private final List list;public improvedList(List list) {this.list list;}public synchronized boolean putIfAbsent(T t){boolean absent !list.contains(t);if (absent)list.add(t);return absent;}Overridepublic synchronized int size() {return list.size();}...}将同步策略文档化在文档中说明客户代码需要了解的线程安全性保证以及代码维护人员需要了解的同步策略。不吝指正。