ReentrantLock源码探究1:非公平锁的获取和释放

​ Sync是ReentrantLock的一个内部类,它继承了AbstractQueuedSynchronizer,即AQS,在CountDownLatch、FutureTask、Semaphore、ReentrantLock等源码中,我们都能看到它们的身影,足见其重要性。此处我们需要先了解下AQS才能更愉悦地阅读源码

​ AQS中是基于FIFO队列的实现,那么它必然包含队列中元素的定义,在这里它是Node:

属 性 定 义
Node SHARED = new Node()   表示Node处于共享模式  
Node EXCLUSIVE = null   表示Node处于独占模式  
int CANCELLED = 1   因为超时或者中断,Node被设置为取消状态,被取消的Node不应该去竞争锁,只能保持取消状态不变,不能转换为其他状态,处于这种状态的Node会被踢出队列,被GC回收  
int SIGNAL = -1   表示这个Node的继任Node被阻塞了,到时需要通知它  
int CONDITION = -2   表示这个Node在条件队列中,因为等待某个条件而被阻塞  
int PROPAGATE = -3   使用在共享模式头Node有可能处于这种状态, 表示锁的下一次获取可以无条件传播  
int waitStatus   0,新Node会处于这种状态  
Node prev   队列中某个Node的前驱Node  
Node next   队列中某个Node的后继Node  
Thread thread   这个Node持有的线程,表示等待锁的线程  
Node nextWaiter   表示下一个等待condition的Node  

AQS中包含的方法有

属性/方法 含 义
Thread exclusiveOwnerThread   这个是AQS父类AbstractOwnableSynchronizer的属性,表示独占模式同步器的当前拥有者  
Node   上面已经介绍过了,FIFO队列的基本单位  
Node head   FIFO队列中的头Node  
Node tail   FIFO队列中的尾Node  
int state   同步状态,0表示未锁  
int getState()   获取同步状态  
setState(int newState)   设置同步状态  
boolean compareAndSetState(int expect, int update)   利用CAS进行State的设置  
long spinForTimeoutThreshold = 1000L   线程自旋等待的时间  
Node enq(final Node node)   插入一个Node到FIFO队列中  
Node addWaiter(Node mode)   为当前线程和指定模式创建并扩充一个等待队列  
void setHead(Node node)   设置队列的头Node  
void unparkSuccessor(Node node)   如果存在的话,唤起Node持有的线程  
void doReleaseShared()   共享模式下做释放锁的动作  
void cancelAcquire(Node node)   取消正在进行的Node获取锁的尝试  
boolean shouldParkAfterFailedAcquire(Node pred, Node node)   在尝试获取锁失败后是否应该禁用当前线程并等待  
void selfInterrupt()   中断当前线程本身  
boolean parkAndCheckInterrupt()   禁用当前线程进入等待状态并中断线程本身  
boolean acquireQueued(final Node node, int arg)   队列中的线程获取锁  
tryAcquire(int arg)   尝试获得锁(由AQS的子类实现它  
tryRelease(int arg)   尝试释放锁(由AQS的子类实现它  
isHeldExclusively()   是否独自持有锁  
acquire(int arg)   获取锁  
release(int arg)   释放锁  
compareAndSetHead(Node update)   利用CAS设置头Node  
compareAndSetTail(Node expect, Node update)   利用CAS设置尾Node  
compareAndSetWaitStatus(Node node, int expect, int update)   利用CAS设置某个Node中的等待状态  

另外在源码中多处使用了CAS,有关CAS的内容,可查看:
乐观锁的一种实现方式:CAS

2.非公平锁的获取过程

假设有两个线程:线程1和线程2尝试获取同一个锁(非公平锁),过程如下

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyfwsp.html