Lock 源码个人理解 (java8)
ReentrantLock lock = new ReentrantLock();
lock.lock();
lock.unlock();
waitStatus节点的几种状态:
-
CANCELLED,值为1,由于在同步队列中等待的线程等待超时或者被中断,需要从同步队列中取消等待,节点进入该状态将不会变化。
-
SIGNAL,值为-1,后继节点的线程处于等待状态,而当前节点的线程如果释放了同步状态或者被取消,将会通知后继节点,使后继节点得以运行。
-
CONDITION,值为-2,节点在等待队列中,节点线程等待在Condition上,当其他线程对Condition调用了signal()方法后,该节点将会从等待队列中转移到同步队列中,加入到对同步状态的获取中。
-
PROPAGATE,值为-3,表示下一次共享式同步状态获取将会无条件地被传播下去。
INITAL,值为0,初始状态。
reentrantLock 的 lock.unlock()开始执行
先来看看tryRelease (尝试释放锁)
- 先获取当前锁的上锁次数 getState()
- 一个线程拿到锁 state = 1
- 当前线程锁重入 state+=1
- 当前线程上锁次数-1
- 判断当前线程是否是独占线程
- 不是,报错
- 如果上锁次数为0
- 释放独占线程
- 更新上锁次数
回到release方法
- 拿到队列的第一个线程
- 如果第一个线程不等于null 且 状态不是完成状态
- 执行unparkSuccessor(顾名思义 释放park住的线程)
- 如果队列头节点状态小于0
- 修改头部节点为初始状态
- 那头线程的下一个线程
- 如果为null 或者 状态大于0
- 拿里头部最近的一个状态小于0的节点
- 唤醒这个节点,让其争取锁