博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《Java并发编程实战》第十四章 构建自己定义的同步工具 读书笔记
阅读量:6157 次
发布时间:2019-06-21

本文共 4246 字,大约阅读时间需要 14 分钟。

一、状态依赖性的管理

有界缓存实现的基类
@ ThreadSafepublic abstract class BaseBoundedBuffer
{ @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
extends BaseBoundedBuffer
{ 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
extends BaseBoundedBuffer
{ 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
extends BaseBoundedBuffer
{ // 条件谓词: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等方法时。一定要持有与条件队列相关的锁。
. 在检查条件谓词之后以及開始运行对应的操作之前。不要释放锁。

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

转载地址:http://qvifa.baihongyu.com/

你可能感兴趣的文章
Skip List——跳表,一个高效的索引技术
查看>>
Yii2单元测试初探
查看>>
五、字典
查看>>
前端js之JavaScript
查看>>
Log4J日志配置详解
查看>>
实验7 BindService模拟通信
查看>>
scanf
查看>>
Socket编程注意接收缓冲区大小
查看>>
SpringMVC初写(五)拦截器
查看>>
检测oracle数据库坏块的方法
查看>>
SQL server 安装教程
查看>>
Linux下ftp和ssh详解
查看>>
跨站脚本功攻击,xss,一个简单的例子让你知道什么是xss攻击
查看>>
js时间和时间戳之间如何转换(汇总)
查看>>
js插件---图片懒加载echo.js结合 Amaze UI ScrollSpy 使用
查看>>
java中string和int的相互转换
查看>>
P1666 前缀单词
查看>>
HTML.2文本
查看>>
Ubuntu unity安装Indicator-Multiload
查看>>
解决Eclipse中新建jsp文件ISO8859-1 编码问题
查看>>