AQS介绍
AQS是一个抽象类,提供了一套通用的控制同步状态,线程阻塞/唤醒,等待队列管理的操作。
平时用的ReentrantLock,CountDownLatch,Semaphore(信号量)都是基于AQS提供API来实现的,他们的不同之处就是对于AQS内部的同步状态(synchronization state,int类型)操作不同,来实现的功能不同。
AQS基于同步状态(synchronization state)主要解决了3个问题:
1、资源的访问是共享的还是独占的,比方说ReentrantLock是独占的,ReentrantReadWriteLock.ReadLock是共享的
2、如何管理等待的线程,使用等待队列
3、无法获取资源,线程的超时和中断机制
AQS的主要方法
如何使用同步状态(synchronization state)才是继承AQS的使用者考虑的问题。
AQS暴露给子类可以使用的方法如下:
1、tryAcquire 独占资源获取 2、tryRelease 独占资源释放 3、tryAcquireShared 共享资源获取 4、tryReleaseShared 共享资源释放 5、isHeldExclusively 是否占用独占资源
AQS框架内部通过一个内部类ConditionObject,实现了Condition接口,以此来为子类提供条件等待的功能。
AQS的内部私有方法:
关于同步状态(synchronization state)AQS提供了3个方法
1、setState 设置同步状态 2、getState 获取同步状态 3、CAS的compareAndSetState 基于unsafe的CAS设置同步状态
等待队列的方法
1、enq 入队操作指定节点(后面介绍),可以进行初始化 2、addWaiter 入队操作节点,节点是当前线程 3、setHead 设置头节点 4、unparkSuccessor 唤醒当前节点的后继节点 5、doReleaseShared 释放共享节点 6、setHeadAndPropagate 设置头节点,并依次唤醒后继节点
操作资源的方法
1、acquire public final 独占地获取资源 2、acquireInterruptibly public final 独占地获取资源(响应中断) 3、acquireInterruptibly public final 独占地获取资源(限时等待) 4、acquireShared public final 共享地获取资源 5、acquireSharedInterruptibly public final 共享地获取资源(响应中断) 6、tryAcquireSharedNanos public final 共享地获取资源(限时等待) 7、等等等........
等待队列
等待队列是以节点(Node)为单位,节点里包装了线程。
节点有2种类型,共享节点和独占节点,独占和共享
节点状态(waitStatus),共享节点和独占节点的状态使用值是不一样的。
1、节点默认状态为0。 2、其中独占结点使用其中的CANCELLED(1)、SIGNAL(-1)、CONDITION(-2),共享结点使用其中的CANCELLED(1)、SIGNAL(-1)、PROPAGATE(-3)。