AQS是java.util.concurrent.locks.AbstractQueuedSynchronizer的简称,直译就是“抽象队列同步器”,它是java中大部分lock类的间接实现者。AQS中实现的各种逻辑非常精妙,在此膜拜一下Doug Lea老爷子。
刚刚有提到AQS间接实现了lock类,检查java中提供的lock类,如ReentrantLock,ReentrantReadWriteLock,StampedLock,CountDownLatch,CyclicBarrier等,内部都有AQS的实现类,完成了不同逻辑来承载不同Lock的实现。
查看源码可知,大致有如下内容:
在AQS的源码中,存在一个由head和tail构成的链表,在知晓它存在的作用前,先了解一下硬件领域的多核CPU架构。
从系统架构来看,目前的商用服务器大体可以分为三类,即对称多处理器结构 (SMP : Symmetric Multi-Processor) ,非一致存储访问结构 (NUMA : Non-Uniform Memory Access) ,以及海量并行处理结构 (MPP : Massive Parallel Processing) 。
即对称多处理器结构,在这种架构中,一台计算机由多个CPU组成,并共享内存和其他资源,所有的CPU都可以平等的访问内存、I/O等。虽然可以同时使用多个CPU,但从外部表现来看,它们就如同一台单CPU机器一样,操作系统将任务队列对称地分布于多个CPU之上,从而极大地提高了整个系统的数据处理能力。
日常的pc机,笔记本,手机还有一些老的服务器都是这个架构,其架构简单,但是拓展性能非常差,从linux 上也能看到:
ls /sys/devices/system/node/# 如果只看到一个node0 那就是smp架构
但是随着CPU数量的增加,每个CPU都要访问共享资源,而资源在某些场景下只能单线程访问,在某些场景下的操作又必须通知到其他CPU,那么这就带来了性能损耗、资源浪费,成为了系统瓶颈。
即非一致存储访问,这种模型的是为了解决smp扩容性很差而提出的技术方案。它按组将CPU分为多模块,每个CPU模块由多个CPU组成,并且具有独立的本地内存、I/O等,模块之间的访问通过互联模块完成(类似远程通信),访问本地资源的速度会远高于访问外部资源。
NUMA架构相当于打包多个SMP架构的CPU,它能较好解决SMP架构存在的扩展问题;但是,在NUMA的单个CPU模块中,虽然控制了CPU数量减少了共享资源的操作时的性能损耗,由于存在互联模块的工作,在CPU模块增加时,并不能线性的增加系统性能。
MPP 提供了另外一种进行系统扩展的方式,它由多个 SMP 服务器通过一定的节点互联网络进行连接,协同工作,完成相同的任务,从用户的角度来看是一个服务器系统。 其基本特征是由多个 SMP 服务器(每个 SMP 服务器称节点)通过节点互联网络连接而成,每个节点只访问自己的本地资源(内存、存储等),是一种完全无共享(Share Nothing)结构,因而扩展能力最好,理论上其扩展无限制,目前的技术可实现512个节点互联,数千个 CPU。 实验证明, SMP 服务器 CPU 利用率最好的情况是 2 至 4 个 CPU [1]。
可以将MMP理解为刀片服务器,每个刀扇里的都是一台独立SMP架构服务器,并且每个刀扇之间均有高性能的网络设备进行交互,保证smp服务器之间的数据传输性能。MMP架构比较依赖管理系统的处理能力来保障通信。
是一种基于单向链表的、高性能、公平的自旋锁。申请加锁的线程通过前驱节点(pre-node)的变量进行自旋。当pre-node解锁后,当前节点会结束自旋并进行加锁。
CLH模型的逻辑:
由于自旋过程中,监控的是前置节点的变量,因此在SMP架构的共享内存模式,能更好的提供性能。
与CLH锁模型的最大区别是,监控的是自己的节点变量,当前置节点解锁后,会主动修改自己的节点变量状态。这种模型解决的是CLH模型在NUMA架构上的不足:当前置节点存在于其他CPU模块时,自旋会导致频繁的调用互联模块。是将自旋调整到了节点自身,互联模块的调用只存在于前置节点解锁的时刻。
MCS模型的逻辑:
说了这么多,其实是想说明AQS中的链表,是为了实现上面的模型,它是针对CLH锁模型的一个变种。后面详细描述AQS中针对head和tail的操作,实际上就是在操作链表的入队和出队。所以说,AQS中的大部分方法,就是在实现CLH锁模型的逻辑。
根据AQS的名称:抽象队列同步器,可以直白的知晓,
对于第三点,之所以这样说,还有由于抽象类这个原因,从整体去看AQS,它的作用并不是去定义同步,而是去实现了一个CLH模型,直白点讲就是实现了如何操作队列及资源,至于何时达到同步,是由实现类去决定的。
由此可知:
本文只是简略的介绍了AQS的组成及每个成员的功能后续内容将会详细展开每个成员,深挖它们的内在逻辑。
推荐阅读
面试必考AQS-AQS概览