美文网首页
Condition和AbstractQueuedSynchron

Condition和AbstractQueuedSynchron

作者: 想做安徒生 | 来源:发表于2018-04-21 23:07 被阅读0次

    点1:AQS即AbstractQueuedSynchronizer,内部维护了一个CLH队列,在JDK的lock实现中深受重用,详细介绍请看,[http://www.importnew.com/22102.html]

    点2:Condition,JDK API中是这样解释的:Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。

    看过ReentrantLock源码的朋友对这两位应该不陌生,今天就和大家一起学习一下这两个兄弟之间的CP暧昧。

    Condition的使用总是伴随着Lock的使用,先跑一个例子给大家:


    image.png
    image.png

    执行结果如下

    image.png

    一、先来分析一下 await()方法

    image.png

    (1)addConditionWaiter()将当前线程包装为node维护在 condition自己的队列中

    (2)fullyRelease(node)将当前线程已经获取到的 lock释放

    (3)while 遍历AQS的队列,看当前节点是否在队列(注意此时的队列已经是AQS的队列)中,不在 说明它还没有竞争锁的资格,所以继续将自己沉睡。直到它被加入到队列(AQS队列)中,那么什么时候被加入队列吗?这里先卖个关子。

    (4)被唤醒后,重新开始正式竞争锁,同样,如果竞争不到还是会将自己沉睡,等待唤醒重新开始竞争。

    image.png

    二、接下来我们看看signal方法,firstWaiter为condition自己维护的一个链表的头结点,取出第一个节点后开始唤醒操作

    image.png

    (1)着重看一下doSignal()

    image.png

    (2)继续往下走,将老的头结点,加入到AQS的等待队列中,这就是上边卖的关子。你一定恍然大悟吧?线程2发出signal信号后,线程1就具备竞争锁的条件了,这时候线程1就会被唤醒加入到AQS队列中;

    image.png

    可以看到,正常情况 ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL)这个判断是不会为true的,所以,不会在这个时候唤醒该线程。只有到发送signal信号的线程用reentrantLock.unlock()后因为它已经被加到AQS的等待队列中,所以才会被唤醒。

    接下来总结一下流程:

    1. 线程waitThread 先执行调用reentrantLock.lock,获取到了锁,此时线程signalThread也去申请锁时候被加入到AQS的等待队列中。

    2. 线程waitThread调用await方法时释放了锁。

    3. 接着waitThread马上被加入到Condition的等待队列中,意味着该线程需要signal信号。

    4. 线程signalThread,因为线程waitThread释放锁的关系,被唤醒,并判断可以获取锁,于是线程signalThread获取锁。

    5. 线程signalThread调用signal方法,这个时候Condition的等待队列中只有线程waitThread一个节点,于是它被唤醒,去竞争锁,此时线程signalThread还未释放锁,所以只能加入到AQS的等待队列中。

    6. signal方法执行完毕,线程signalThread调用reentrantLock.unLock()方法,释放锁。这个时候因为AQS中只有线程waitThread,于是,AQS释放锁后按从头到尾的顺序唤醒线程时,线程waitThread被唤醒,于是线程waitThread继续执行。

    7. 直到释放所整个过程执行完毕。

    总的来看:整个过程是AQS 和Condition这哥俩的等待队列相互移动处理来实现的,Condition做为条件类,内部维护了一个等待队列,在合适的机会将自己的队列的节点移除并将设置到AQS队列中,让其去争夺lock,Condition拥有修改AQS队列的特权。

    本文参考自:http://www.importnew.com/9281.html

    http://www.importnew.com/22102.html

    相关文章

      网友评论

          本文标题:Condition和AbstractQueuedSynchron

          本文链接:https://www.haomeiwen.com/subject/seaflftx.html