AQS的核心组成
1.AQS的三个重要属性:head、tail、state。
head:CLH队列的头节点。
tail:CLH队列的尾节点。
state:锁的状态。
LOCK的底层原理就是对state进行CAS操作,CLH队列记录尝试获取该锁的线程及其状态。
其中head和tail均为AQS的静态内部类Node的实例,Node由prev、next、waiter、status构成
prev:前驱节点。
next:后驱节点。
waiter:该节点所代表的线程。
status:线程所处的状态。waiting、cancelled、cond。
2.AQS的四个重要方法:使得锁有两种形式,独占锁和共享锁。
1. acquire(),获取独占锁,最终会调用tryAcquire()方法。
2. release(),释放独占锁,最终会调用tryRelease()方法。
3. acquireShared(),获取共享锁,最终会调用tryAcquireShared()方法。
4. releaseShared(),释放共享锁,最终会调用tryReleaseShared()方法。
上述方法均被final修饰,子类无法重写。tryAcquire()、tryRelease()、tryAcquireShared()、tryReleaseShared()会被子类(ReentrantLock、CountdownLatch等)重写,来实现具体锁的逻辑。
3.AQS的ConditionObject类,是Condition接口的实现类,可与ReentrantLock结合使用。 ConditionObject的底层数据结构为一个单向队列,用于存储等待在给定条件上的线程节点。
重要方法:
1.signal():唤醒单向队列中的第一个线程。
2.signalAll():唤醒单向队列中的所有线程。
3.await():将当前线程加入到单向队列中。最终也会调用AQS的acquire()方法尝试获取锁,获取失败则将节点也加入CLH队列。
ConditionObject是如何与AQS产生联系的?
ConditionObject中单向队列的节点(ConditionNode)和AQS中CLH队列的节点(Node)是同一个节点。ConditionNode是Node的子类,因此使用AQS的acquire()方法时可以传入ConditionNode对象。
基于Java1.8的AQS的acquire方法源码解析:链接:
https://blog.csdn.net/weixin_38106322/article/details/107121149