Java并发编程实战
来源:互联网 发布:大型系统网络拓扑图 编辑:程序博客网 时间:2024/05/01 06:15
如何通过线程安全的组件组合设计线程安全的类?
首先要封装所有状态,封装简化了安全类的实现过程。
设计线程安全的类,需考虑三个基本要素
- 找出构成对象状态的所有变量
- 找出约束状态变量的约束条件–>不变性条件和后验条件
- 建立对象状态的并发访问管理策略
要满足对象的状态的约束条件,就需要借助于原子性和封装性。
依赖状态的操作
如果某个操作中包含有基于状态的先验条件(Precondition),如没有则添加,那么这个操作称为依赖状态操作 。
实现等待条件为真才执行的操作的方法有:
内置机制(如等待和通知);现有的类库中的类(如BlockingQueue)。
状态的所有权
对象封装了它拥有的状态,则对象对它封装的状态拥有所有权。
如果发布一个可变对象的引用,就不在独占所有权。
容器类表现为所有权分离,容器类拥有自身的状态,而客户代码则拥有容器内各个对象的状态。
通过封闭和加锁实现线程安全的类
public class PersonSet { private final Set<Person> mySet = new HashSet<Person>(); public synchronized void addPerson(Person p) { mySet.add(p); } public synchronized boolean containsPerson(Person p) { return mySet.contains(p); } interface Person { }}
PersonSet类是线程安全的类,它将状态(mySet )封装起来,并对访问这个状态的方法进行加锁。
但Person类如果是可变的,需要设计成线程安全的类来安全的使用Person对象。
创建线程安全类的策略1 - Java监视器模式
Java监视器模式的对象会把对象的所有可变状态都封装起来,并有对象自己的内置锁来保护。
私有锁
public class PrivateLock { private final Object myLock = new Object(); Widget widget; void someMethod() { synchronized (myLock) { // Access or modify the state of widget } }}
创建线程安全类的策略2 - 线程安全性的委托
通过对象的组合,将线程安全性委托给现有的线程安全类。
如果一个类是由多个独立且线程安全的状态变量组成,并且在所有的操作中都不包含无效状态的转换,那么可以将线程安全性委托给底层的状态变量。
示例:PersonList将线程安全性委托给底层的线程安全状态变量
public class PersonList { private final List<Person> myList = new CopyOnWriteArrayList<Person>();//安全性委托 public void addPerson(Person p) { myList.add(p); } public boolean containsPerson(Person p) { return myList.contains(p); } interface Person { }}
线程安全性委托要考虑下列问题:
1. 状态变量要是线程安全的。
2. 多个线程安全的状态变量是独立的。
3. 多个线程安全的状态变量有不变性条件约束–不能直接委托,需要对操作加锁。
4. 类含有复合操作– 不能直接委托,需要对操作加锁。
5. 什么条件下可以发布底层的状态变量?
如果一个状态变量是线程安全的,并且没有任何不变性条件约束它的值,在变量的操作上也不存在任何不允许的状态转换,那么就可以安全地发布这个变量。
在现有的线程安全类中添加功能
1.修改原始的类
2.扩展原始类(继承)
3.扩展原始类的功能,将扩展代码放到一个“辅助类”中–通过客户端加锁。
4.组合–通过客户端加锁。
示例: 扩展原始类的功能
@NotThreadSafeclass BadListHelper <E> { public List<E> list = Collections.synchronizedList(new ArrayList<E>()); public synchronized boolean putIfAbsent(E x) {//和list对象不是同一锁 boolean absent = !list.contains(x); if (absent) list.add(x); return absent; }}@ThreadSafeclass GoodListHelper <E> { public List<E> list = Collections.synchronizedList(new ArrayList<E>()); public boolean putIfAbsent(E x) { synchronized (list) {//和list对象是同一个锁 boolean absent = !list.contains(x); if (absent) list.add(x); return absent; } }}
示例: 组合
@ThreadSafepublic class ImprovedList<T> implements List<T> { private final List<T> list; /** * PRE: list argument is thread-safe. */ public ImprovedList(List<T> list) { this.list = list; } public synchronized boolean putIfAbsent(T x) { boolean contains = list.contains(x); if (contains) list.add(x); return !contains; } // Plain vanilla delegation for List methods. // Mutative methods must be synchronized to ensure atomicity of putIfAbsent. public int size() { return list.size(); } public boolean isEmpty() { return list.isEmpty(); } public boolean contains(Object o) { return list.contains(o); } public Iterator<T> iterator() { return list.iterator(); } public Object[] toArray() { return list.toArray(); } public <T> T[] toArray(T[] a) { return list.toArray(a); } public synchronized boolean add(T e) { return list.add(e); } public synchronized boolean remove(Object o) { return list.remove(o); } public boolean containsAll(Collection<?> c) { return list.containsAll(c); } public synchronized boolean addAll(Collection<? extends T> c) { return list.addAll(c); } public synchronized boolean addAll(int index, Collection<? extends T> c) { return list.addAll(index, c); } public synchronized boolean removeAll(Collection<?> c) { return list.removeAll(c); } public synchronized boolean retainAll(Collection<?> c) { return list.retainAll(c); } public boolean equals(Object o) { return list.equals(o); } public int hashCode() { return list.hashCode(); } public T get(int index) { return list.get(index); } public T set(int index, T element) { return list.set(index, element); } public void add(int index, T element) { list.add(index, element); } public T remove(int index) { return list.remove(index); } public int indexOf(Object o) { return list.indexOf(o); } public int lastIndexOf(Object o) { return list.lastIndexOf(o); } public ListIterator<T> listIterator() { return list.listIterator(); } public ListIterator<T> listIterator(int index) { return list.listIterator(index); } public List<T> subList(int fromIndex, int toIndex) { return list.subList(fromIndex, toIndex); } public synchronized void clear() { list.clear(); }}
- Java并发编程实战
- Java并发编程实战--
- Java并发编程实战-
- Java 并发编程实战
- java并发编程实战
- Java并发编程实战
- Java并发编程实战
- Java并发编程实战
- Java并发编程实战
- Java并发编程实战
- Java并发编程实战
- Java并发编程实战
- Java并发编程实战
- Java并发编程实战
- Java并发编程实战
- Java并发编程实战
- Java并发编程实战
- Java并发编程实战
- find函数用法详解
- Java 多线程(九)——ThreadLocal类
- HashMap和HashSet的区别
- POJ3615
- Hdu 1846 Brave Game 巴什博奕
- Java并发编程实战
- 基于QT的学生信息管理系统开发
- mysql安装
- 加密与解密入门
- [深度学习论文笔记][CVPR 16]Deep Metric Learning via Lifted Structured Feature Embedding
- HDU
- 稀疏矩阵的压缩存储与转置与加法
- linux安装jupyter
- hdu 1024和hdu 1244 两个最大和子序列 dp 优化