知识卡片
条件队列分离等待
内容
Condition 把”等待业务条件”和”竞争同步锁”拆开,用独立于同步队列的条件队列实现:await() 新建节点入队并释放锁;signal() 把节点转移到同步队列,被唤醒线程要重新竞争锁。相比 synchronized 只有一个 wait-set,一个 Lock 可开出多个 Condition,如 [[生产消费靠条件]] 的 NOT_FULL/NOT_EMPTY。
参考来源
- 位置:《Java高并发核心编程.卷2,多线程、锁、JMM、JUC、高并发设计模式》第6章《AQS抽象同步器的核心原理》6.9.2节《await()等待方法原理》、6.9.3节《signal()唤醒方法原理》(源文件:_epub-src/OEBPS/Text/chapter226.xhtml、chapter227.xhtml)
- 结论依据:原文给出await()的流程——“执行await()时,会新创建一个节点并放入Condition队列尾部。然后释放锁,并唤醒AQS同步队列中的头节点的后一个节点……直到该节点离开等待队列,重新回到同步队列成为同步节点……开始调用acquireQueued()不断尝试拿锁”,以及signal()“通过enq()方法自旋……将条件队列中的头节点放入AQS同步队列尾部”,因此推出本卡结论。
- 原始内容:执行await()时,会新创建一个节点并放入Condition队列尾部。然后释放锁,并唤醒AQS同步队列中的头节点的后一个节点……线程调用await()方法时……await()方法需要把该线程从AQS队列挪到Condition等待队列里……通过enq()方法自旋……将条件队列中的头节点放入AQS同步队列尾部。