AQS(AbstractQueuedSynchronizer),译抽象的队列同步器。
1、AQS是构建锁和其他同步器主键的重量级基础框架及整个JUC体系的基石
2、通过内置的FIFO队列来完成资源获取线程的排队工作,并通过一个int变量表示持有锁的状态
经典用处:
ReentrantLock
内部有一个sync类继承AQS
CountDownLatch
内部有一个sync类继承AQS
RentrantReadWriteLock
内部有一个sync类继承AQS
Semaphore
内部有一个sync类继承AQS
基础定义:
锁:面向锁的使用者
定义了程序员和锁交互的使用层API。隐藏了实现细节,调用即可,如上面说到的4种锁实现
同步器:面向锁的实现者
规范化锁的实现,屏蔽了同步状态管理、阻塞线程排队和通知、唤醒机制等
作用:
加锁导致阻塞
有阻塞就要排队,实现排队就需要某种形式的队列来管理
抢到资源的线程直接处理,抢不到的必然涉及排队等待机制,抢占失败的线程得继续等待
但等待过程仍然保留获取锁的可能且获取锁流程仍在继续
AQS:
如果共享资源被占用,就需要一定的阻塞等待唤醒机制来保证锁分配。这个机制主要用的是CLH队列的变体来实现,将暂时获取不到锁的线程加入到队列中,这个队列就是AQS的抽象表现。它将请求公共资源的线程封装成队列中的结点(Node),通过CAS,自旋以及LockSupport.park()的方式,维护state变量的状态,使并发达到同步的控制效果
AQS工作模式
使用volatile的int类型的成员变量来表示同步状态,通过内置的FIFO队列来完成资源获取的排队工作,将每条要去抢占资源的线程封装成一个结点来实现锁的分配,通过CAS完成对state的修改。
AQS自身:
1、AQS的int变量
AQS的同步状态State成员变量
如 银行帮你业务的受理窗口状态,0=没人,大于等于1相当于有人占用
2、AQS的CLH队列
一个双向队列,通过自旋等待,state判断是否阻塞,从尾部入队头部出队
3、总结
有阻塞就有排队,实现排队必然需要队列
AQS = state + CLH队列
Node:
1、node的int变量
node的等待状态waitState成员变量
等候区的其他顾客(其他线程)的等待状态,队列中每一个排队的人就是一个node
2、内部结构
CLH列队就是一个一个Node队列
node结点= waitState + 前后指针指向
3、属性说明
模式:共享和排他
waitSstate:0=默认,1=取消,2=等待唤醒,3=共享时才用到,-1=准备好了等资源释放
如排队状态的顾客,可以取消不排队
AQS结构图: