《Java并发编程实战》第十四章 构建自定义的同步工具 读书笔记
来源:互联网 发布:淘宝上卖的火麻能飞吗 编辑:程序博客网 时间:2024/06/03 16:33
一、状态依赖性的管理
有界缓存实现的基类
@ ThreadSafepublic abstract class BaseBoundedBuffer<E> { @GuardeBy( "this" ) private final E[] buf; @GuardeBy( "this" ) private int tail; @GuardeBy( "this" ) private int head; @GuardeBy( "this" ) private int count; protected BaseBoundedBuffer( int capacity) { this .buf = (E[]) new Object[capacity]; } protected synchronized final void doPut(E E) { buf[tail] = E; if (++tail == buf.length) { tail = 0; } ++count; } protected synchronized final E doTake() { E E = buf[head]; buf[head] = null ; if (++head == buf.length) { head = 0; } --count; return E; } public synchronized final boolean isFull() { return count == buf.length; } public synchronized final boolean isEmpty() { return count == 0; }}
1 示例:将前提条件的失败传递给调用者
@ ThreadSafepublic class GrumpyBoundedBuffer<V> extends BaseBoundedBuffer<V> { public GrumpyBoundedBuffer( int size){ super (size); } public synchronized void put(V v){ if (isFull()){ throw new BufferFullException (); } doPut(v); } public synchronized V take(){ if (isEmpty()) throw new BufferEmptyExeption (); return doTake(); }}
缓存为空或者已满都不是异常情况,使用者必须要捕获这些异常才能进行正确的处理。
while (true ){ try { V item = buffer.take(); // 对于item执行一些操作 break ; } catch (BufferEmptyException e) { Thread. sleep(SLEEP_GRANULARITY ); } }
2 示例:通过轮询与休眠来实现简单的阻塞
从上面的代码可以看出,阻塞与出现异常都需要方法的使用者来处理,现在尝试都封装到有界缓存中。
@ ThreadSafepublic class SleepyBoundedBuffer<V> extends BaseBoundedBuffer<V> { public SleepyBoundedBuffer( int size) { super (size); } public void put(V v) throws InterruptedException{ while (true ){ synchronized (this ){ if (!isFull()){ doPut(v); return ; } } Thread.sleep(SLEEP_GRANULARITY); } } public V take() throws InterruptedException{ while (true ){ synchronized (this ){ if (!isEmpty()){ return doTake(); } } Thread.sleep(SLEEP_GRANULARITY); } }}
3 条件队列
不需要使用while(true),改为使用wait、notifyAll
@ ThreadSafepublic class BoundedBuffer<V> extends BaseBoundedBuffer<V> { // 条件谓词:not-full (!isFull()) // 条件谓词:not-empty (!isEmpty()) public BoundedBuffer( int size) { super (size); } // 阻塞并直道:not-full public synchronized void put(V v) throws InterruptedException{ while (isFull()){ wait(); } doPut(v); notifyAll(); } // 阻塞并直道:not-empty public synchronized V take() throws InterruptedException{ while (isEmpty()){ wait(); } V v = doTake(); notifyAll(); return v; }}
二、使用条件队列
1 条件谓词要想正确地使用条件队列,关键是找出对象在哪个条件谓词上等待。
2 过早唤醒
例如:内置条件队列中有多个条件谓语,此时如果调用notifyAll其含义是通知所有wait,但是并不一定所有条件谓语都满足执行条件。
当使用条件等待时(例如Object.wait或Condition.await):
. 通常都有一个条件谓词--包括一些对象状态的测试,线程在执行前必须首先通过这些测试。
. 在调用wait之前测试条件谓词,并且从wait中返回时再次进行测试。
. 在一个循环中调用wait。
. 确保使用与条件队列相关的锁来保护构成条件谓词的各个状态变量。
. 当调用wait、notify或notifyAll等方法时,一定要持有与条件队列相关的锁。
. 在检查条件谓词之后以及开始执行相应的操作之前,不要释放锁。
. 通常都有一个条件谓词--包括一些对象状态的测试,线程在执行前必须首先通过这些测试。
. 在调用wait之前测试条件谓词,并且从wait中返回时再次进行测试。
. 在一个循环中调用wait。
. 确保使用与条件队列相关的锁来保护构成条件谓词的各个状态变量。
. 当调用wait、notify或notifyAll等方法时,一定要持有与条件队列相关的锁。
. 在检查条件谓词之后以及开始执行相应的操作之前,不要释放锁。
3 丢失的信号
已经满足通知的条件发出通知,但是之后才进入阻塞wait状态,所以wait永远等不到在其前面发出的notify。
4 通知
5 示例:阀门类
6 子类的安全问题
7 封装条件队列
8 入口协议与出口协议
三、显式的Condition对象
四、Synchronizer剖析
五、AbstractQueuedSynchronizer
六、java.util.concurrent同步器类中的 AQS
1 ReentrantLock
2 Semaphore与CountDownLatch
3 FutureTask
4 ReentrantReadWriteLock
2 0
- 《Java并发编程实战》第十四章 构建自定义的同步工具 读书笔记
- Java并发编程实战(学习笔记 十三 第十四章 构建自定义的同步工具 上)
- Java并发编程实战(学习笔记 十三 第十四章 构建自定义的同步工具 下 )
- java并发编程实战-构建自定义的同步工具
- 并发编程实战学习笔记(十)-构建自定义的同步工具
- [Java Concurrency in Practice]第十四章 构建自定义的同步工具
- Java多线程并发编程之构建自定义同步工具
- java并发编程实践学习(14 ) 构建自定义的同步工具
- 《Java并发编程实战》第五章 同步容器类 读书笔记
- java多线程编程-构建自定义的同步工具
- java并发编程:自定义同步工具
- 《Java并发编程实战》读书笔记二:构建线程安全
- 《Java并发编程实战》读书笔记五:深入理解同步实现
- 《Java并发编程实战》第三章 对象的共享 读书笔记
- 《Java并发编程实战》第四章 对象的组合 读书笔记
- 《Java并发编程实战》第十五章 原子变量与非阻塞同步机制 读书笔记
- 《Java并发编程实战》读书笔记
- 《Java并发编程实战》读书笔记
- Android 调用摄像头功能【拍照】
- Cocos2d-x Auto-batching 浅浅的”深入分析”
- spring IOC和DI
- 怎样快速学习一门新技术
- Android内存泄漏分析及调试
- 《Java并发编程实战》第十四章 构建自定义的同步工具 读书笔记
- 为什么说Android才是游戏开发者的乐土?
- 盲人it工程师
- 循环-15. 统计素数并求和(20)
- LeetCode: Binary Tree Level Order Traversal [102]
- 作为一个新人,怎样学习嵌入式Linux?(韦东山)
- LeetCode: Binary Tree Zigzag Level Order Traversal [103]
- SharePoint 2010 自定义字段开发
- 循环-16. 猴子吃桃问题(15)