AQS 是JUC并发包中ReentrantLock,ReentrantReadWriteLock,CountDownLatch,CyclicBarrier等类的底层实现。
AQS主要是维护了一个CLH阻塞队列(双向队列)
image.png
这个队列中保存的是没有获得锁的线程。
线程A
具体过程如下:
1.有A,B两个线程去获取资源,A线程通过Lock方法获取锁资源。2.B线程接着去调用Lock方法想获取已经属于A的锁资源。3.B线程会因为获取锁失败(通过CAS操作对状态位进行标记来获取锁),被封装成Node节点放入到AQS CLH双向队列中4.调用LockSupport.park()将线程阻塞挂起。5.同理其他再想争用线程A锁的线程也会被加入CLH队列中,并被挂起。我们知道Lock和synchronized的一大区别就是Lock支持条件的,Lock和condition的关系是1:n的,即一个lock可以有多个条件
image.png
Lock和使用condition步骤如下:
1.线程A需要通过lock方法先获得lock锁。2.当线程A调用到condition.await()释放锁(通过CAS操作对状态进行标记)3.阻塞线程A4.线程A封装成node节点放入条件队列中(每个条件有自己的条件队列,和AQS的CLH队列无关)5.由于资源被释放,因此去AQS中唤起一个之前被阻塞挂起的线程。AQS概述已经讲完了,下篇介绍下AQS源码层面相关。