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了,感觉能猜到他是怎么做的了

最后更新于

这有帮助吗?