06-Condition
在第二章第5节已经说了Conditon, 当时用Condition做了一个有界队列。
Condition是Lock的附属物,Condition定义了等待/通知两种类型的方法,当前线程调用这些方法时,需要提前获取到Condition对象关联的锁。
一个锁可以搞多个Condition
Condition的API
public interface Condition {
/**
* 让当前线程进入等待状态直到被通知或者被中断,当前线程重新进入运行状态且从await方法返回的情况如下
* 1. 其他线程调用了该Condition的signal 或signalAll
* 2. 其他线程调用interrupt中断了当前线程
* @throws InterruptedException
*/
void await() throws InterruptedException;
/**
* 等价上面那个
* @param time
* @param unit
* @return
* @throws InterruptedException
*/
boolean await(long time, TimeUnit unit) throws InterruptedException;
/**
* 指定到某个时间还没被通知且没被中断直接返回,提前被通知了返回true,否则false
* @param deadline
* @return
* @throws InterruptedException
*/
boolean awaitUntil(Date deadline) throws InterruptedException;
/**
* 唤醒等待在Condition上的一个线程
*/
void signal();
/**
* 唤醒所有等待在Condition上的线程
*/
void signalAll();
}基本原理
在ReentrantLock里边搜newCondition
可见ConditionObject应该是实现了Condition接口,去看一眼
发现ConditionObject是AQS的内部类
等待队列
去看ConditionObject, 会发现里边也和AQS同步队列类似,有一个队列结构,队列节点居然和之前说的同步队列的节点是一样的,世间真奇妙
ConditionObject里边有两个重要成员变量firstWaiter,lastWaiter,对比AQS,AQS有head和tail,这个是双向队列的模板,太巧了
当前线程调用Condition.await()方法,将会以当前线程构造节点,并将节点从尾部加入等待队列。
简单理解,await就是根据当前线程信息构建Node节点,加入等待队列,同时由于调用await的一定是获取锁的,所以我们要移除当前线程在同步队列的那个节点,其实就是首节点,首节点要变,首节点的线程就要释放锁,其实就是当前线程会释放锁。
上边这段描述是我看简单搂了一眼源码写的,发现竟然和书上意思一样,开心~
接下来就是看signal了,感觉能猜到他是怎么做的了
最后更新于
这有帮助吗?