硬核剖析Java锁底层AQS源码,深入理解底层架构设计( 四 )

4.4 signal唤醒signal唤醒的流程:

硬核剖析Java锁底层AQS源码,深入理解底层架构设计

文章插图
唤醒条件队列的头节点,并追加到同步队列末尾 。
// 唤醒条件队列的头节点public final void signal() {// 1. 只有持有锁的线程才能调用signal方法if (!isHeldExclusively())throw new IllegalMonitorStateException();// 2. 找到条件队列的头节点Node first = firstWaiter;if (first != null)// 3. 开始唤醒doSignal(first);}// 实际的唤醒方法private void doSignal(Node first) {do {// 4. 从条件队列中移除头节点if ((firstWaiter = first.nextWaiter) == null)lastWaiter = null;first.nextWaiter = null;// 5. 使用死循环,一定要转移一个节点到同步队列} while (!transferForSignal(first) &&(first = firstWaiter) != null);}到底是怎么转移到同步队列末尾的?
// 实际转移方法final boolean transferForSignal(Node node) {// 1. 把节点状态从CONDITION改成0if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))return false;// 2. 使用死循环的方式,追加到同步队列末尾(前面已经讲过)Node p = enq(node);int ws = p.waitStatus;// 3. 把前驱节点状态设置SIGNAL(通知他,别忘了唤醒老弟)if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))LockSupport.unpark(node.thread);return true;}5. 总结看完整个AQS的源码,是不是完全理解了AQS加锁、释放锁、以及同步队列和条件队列数据流转的逻辑了 。
硬核剖析Java锁底层AQS源码,深入理解底层架构设计

文章插图
连AQS这么复杂的源码你都搞清楚了,下篇带你一块学习ReentrantLock源码,应该就轻松多了 。
我是「一灯架构」,如果本文对你有帮助,欢迎各位小伙伴点赞、评论和关注,感谢各位老铁,我们下期见

硬核剖析Java锁底层AQS源码,深入理解底层架构设计

文章插图

经验总结扩展阅读