什么是AQS
AQS是AbstractQueuedSynchronizer(抽象队列同步器),并发包的一个基本组件,用来实现各种锁和各种同步组件。它包括并发中的核心组件,例如状态变量、锁定线程和等待队列。我们常用的ReentrantLock、CountDownLatch等基础类库都是基于AQS实现的。
AQS原理及结构
AQS的核心思想是,如果请求的共享资源空闲,则将当前请求该资源的线程设置为有效的工作线程,并将共享资源设置为锁定状态;如果共享资源被占用,则通过基于双向链表的队列等待。
AQS同步状态——状态。AQS维护了一个字段state,表示同步状态,由Volatile修饰,用于显示当前关键资源的锁状态。
这里有几种访问该字段的方法:
方法名称说明protectedfinalintgetState()intupdate)使用CAS更新ReentrantLock中的State
AQS
ReentrantLock初始状态,AQS中的状态为0,加锁线程为null,然后调用lock方法以非公平锁作为一个示例:
staticfinalclassNonfairSyncextendsSync{
privatestaticfinallongserialVersionUID=7316153563782823691L;
的
最终无效锁(){
如果(compareAndSetState(0,1))
setExclusiveOwnerThread(Thread.currentThread());
别的
获取(1);
}
的protectedfinalbooleantryAcquire(intacquires){
返回非公平尝试获取(获取);
}
}
CAS将状态变为1,锁定线程成为调用线程。当这个线程来锁定状态时,就会变成2,其他的调用会被封装到一个线程节点中,进入等待队列。
再看ReentrantLock调用解锁方法
publicvoidunlock(){
同步。发布(1);
}
调用AQS的release方法
publicfinalbooleanrelease(intarg){
如果(tryRelease(arg)){
节点h=头;
如果(h!=null&&h.waitStatus!=0)
unparkSuccessor(h);
返回真;
}
返回假;
}
其实tryRelease会调用setState方法将状态数减一。如果状态值为0,锁将被完全释放,“锁定线程”变量也将被设置为null。接下来,它将从等待队列开始。队列的头部唤醒线程2并尝试再次锁定。其实就是这么多逻辑,大家也可以看看源码,看看是怎么实现的。
参考
https://mp.weixin.qq.com/s/s/sA01gxC4EbgypCsQt5pVog
https://mp.weixin.qq.com/s/zdn54VeNSsabwD3CBd3CBvSoA
关注♷:蜜蜂科技窝了解更多知识