ReentrantLock
内部继承了AQS
AQS类主要就是一个State和一个双向队列
CAS修改state值去获取锁
Node就是队列中的节点包含了几个重要标识
-
EXCLUSIVE
- 排它锁标识
-
CANCELLED=1
- 失效了
-
SIGNAL=-1
- 后继节点需要被唤醒
相比synchronized,ReentrantLock增加了一些高级功能
lock.lockInterruptibly()等待可中断
ReentrantLock(boolean fair)可实现公平锁,默认是非公平的
可实现选择性通知
- 需要借助于Condition接口与newCondition()方法
常用方法
lock()
acquire()
- 公平锁入口方法
tryAcquire()
- 尝试获取锁,失败了,则封装成一个Node去双向队列排队
addWaiter
- 获取锁失败,创建并设置他的前节点,设置当前线程,等待
acquireQueued
- 已经将Node加入到了双向队列,然后执行当前方法
- 判断是不是头结点,尝试获取锁资源
unlock()
独占锁、可重入锁
公平锁与非公平锁区别
- 非公平锁在调用 lock 后,首先就会调用 CAS 进行一次抢锁,如果这个时候恰巧锁没有被占用,那么直接就获取到锁返回了。
- 非公平锁在 CAS 失败后,和公平锁一样都会进入到 tryAcquire 方法,在 tryAcquire 方法中,如果发现锁这个时候被释放了(state == 0),非公平锁会直接 CAS 抢锁,但是公平锁会判断等待队列是否有线程处于等待状态,如果有则不去抢锁,乖乖排到后面