重大发现,AQS加锁机制竟然跟Synchronized有惊人的相似( 二 )


我们再看一下AQS实际的加锁机制是怎么设计的?是不是跟Synchronized相似?

重大发现,AQS加锁机制竟然跟Synchronized有惊人的相似

文章插图
AQS的加锁流程并不复杂,只要理解了同步队列和条件队列,以及它们之间的数据流转,就算彻底理解了AQS 。
  1. 当多个线程竞争AQS锁时,如果有个线程获取到锁,就把ower线程设置为自己
  2. 没有竞争到锁的线程,在同步队列中阻塞(同步队列采用双向链表,尾插法) 。
  3. 持有锁的线程调用await方法,释放锁,追加到条件队列的末尾(条件队列采用单链表,尾插法) 。
  4. 持有锁的线程调用signal方法,唤醒条件队列的头节点,并转移到同步队列的末尾 。
  5. 同步队列的头节点优先获取到锁
可以看到AQS和Synchronized的加锁流程几乎是一模一样的,AQS中同步队列就是Synchronized中EntryList,AQS中条件队列就是Synchronized中的waitSet,两个队列之间的数据转移流程也是一样的 。
3. 总结AQS跟Synchronized的加锁流程是一样的,都是通过同步队列和条件队列实现的,阻塞状态的线程被放到同步队列中,等待状态的线程被放到条件队列中,从条件队列唤醒的线程又被转移到同步队列末尾,一块竞争锁 。
看完AQS加锁流程,还没有人不懂AQS的?
下篇文章再讲一下AQS加锁具体的源码实现 。里面有很多精巧的设计,值得我们学习 。
比如:
为什么同步队列要设计成双向链表?而条件队列要设计成单链表?
为什么AQS加锁性能这么好(乐观锁CAS使用)?
同步队列和条件队列中节点怎么用一个对象实现?
释放锁后,怎么唤醒同步队列中线程?
我是「一灯架构」,如果本文对你有帮助,欢迎各位小伙伴点赞、评论和关注,感谢各位老铁,我们下期见

重大发现,AQS加锁机制竟然跟Synchronized有惊人的相似

文章插图
【重大发现,AQS加锁机制竟然跟Synchronized有惊人的相似】

经验总结扩展阅读