深入解析Condition的底层实现原理

一、原理概述

在AQS中,存在两个FIFO队列:同步队列和等待队列。等待队列是由Condition内部实现的,是一个虚拟的FIFO单向队列
在这里插入图片描述
释义: AQS中tali和head主要构成了一个FIFO双向的同步队列,AQS中Condition构成了一个FIFO单向等待队列。Condition是AQS内部类,每个condition对象保存了firstWaiter和lastWaiter作为队列首节点和尾节点,每个节点使用Node.nextWaiter保存下一个节点的引用,因此等待队列是一个单向队列。

二、具体实现

2.1 等待的实现

主要步骤为:

  1. 当线程调用Condition.await()后,会当前线程封装成Node节点,并将节点加入到等待队列的尾部,然后释放同步state状态(释放锁),唤醒同步队列中的后继节点,当前线程进入等待状态。如下图所示:
    在这里插入图片描述
注意1Condition拥有首尾节点的引用,新增节点只需将尾节点的nextWaiter指向它,然后更新尾节点即可。
注意2Condition.await()节点引用更新的过程并没有CAS保证,原因在于调用await()方法的线程必定是获取
到锁的线程,利用锁来保证线程安全。
注意3:同步队列的首节点并不会直接加入等待队列,而是把当前线程构封装成一个新的节点并将其加入等待队列
中。

2.2 通知的实现

  1. 执行signal()唤醒线程时,先判断当前线程是否持有state锁,所以能够调用signal()方法的线程一定时持有了同步锁state;
  2. 【自旋】唤醒等待队列中等待时间最长的节点(firstWaiter首节点),在唤醒firstWaiter节点之前,会将等待队列首节点移动同步队列中。
    在这里插入图片描述

2.3 总结

  1. Condition通知的本质就是等待队列和同步队列的交互,和Object的wait()/notify()机制一样。Condition是基于同步锁state实现的,object是基于monitor模式实现的;
  2. 一个lock(AQS)可以有多个等待队列,只有一个同步队列
  3. Condition.await()方法执行时,会将同步队列里的state锁释放掉,把线程重新封装成node节点添加到等待队列中;Condition.signal()方法执行时,会将等待队列中的首节点移动同步队列尾部,直到state锁被获取才唤醒。
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

桃花猿

客官,赏点打酒钱

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值