//指向队列首元素的头指针
private transient volatile Node head;
//指向队列尾元素的尾指针
private transient volatile Node tail;
//该锁被线程重入的次数。当state为0表示该锁不被任何线程持有;当state为1表示线程恰好持有该锁1次(未重入);当state大于1则表示锁被线程重入state次
private volatile int state;
//当前占用锁的线程
private transient Thread exclusiveOwnerThread;
//同步队列
abstract static class Sync extends AbstractQueuedSynchronizer
// 非公平锁
static final class NonfairSync extends Sync
// 公平锁
static final class FairSync extends Sync
// 默认非公平锁
public ReentrantLock() {
sync = new NonfairSync();
}
// 加锁
public void lock() {
sync.lock();
}
非公平锁加锁流程:
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
final void lock() {
//使用CAS尝试更新state的从0默认值更新到1,如果更新成功,说明当前线程可以获取锁
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread()); //将当前线程标记为占有锁的线程
else
acquire(1); //使用CAS获取锁失败,继续尝试获取锁
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
//获取锁
public final void acquire(int arg) {
if (!tryAcquire(arg) && //当前线程尝试获取锁,若获取成功返回true,否则false
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
//尝试获取锁
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
//非公平锁尝试获取锁
final boolean nonfairTryAcquire(int acquires) {
//获取当前线程
final Thread current = Thread.currentThread();
//获取重入锁状态
int c = getState();
//说明当前线程可以获取锁
if (c == 0) {
if (compareAndSetState(0, acquires)) { //获取锁成功
setExclusiveOwnerThread(current); //将当前线程标记为占有锁的线程
return true; //获取锁成功,非重入
}
}
else if (current == getExclusiveOwnerThread()) { //如果当前线程已经获取锁,重入次数加1
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc); //设置状态值
return true; 获取锁成功,重入
}
return false; //走到这里说明尝试获取锁失败
}
//获取锁失败,增加到等待队列
private Node addWaiter(Node mode) {
//创建一个新节点,并将当前线程实例封装在内部,mode为null
Node node = new Node(Thread.currentThread(), mode);
//获取等待队列原尾部节点
Node pred = tail;
//快速入队逻辑
if (pred != null) { //如果尾部节点不为null
node.prev = pred; //设置新建节点的pre指针指向原尾部节点
if (compareAndSetTail(pred, node)) { //使用CAS更新尾部节点,将当前节点设置成尾节点
pred.next = node; //将原尾部节点next指针指向当前节点(新的尾节点)
return node;
}
}
enq(node); //入队
return node;
}
//入队逻辑
private Node enq(final Node node) {
for (;;) {
Node t = tail;
if (t == null) { // 如果尾部节点为空,初始化头节点
if (compareAndSetHead(new Node()))
tail = head; //将头和尾指向同节点
} else { //当尾部节点不为空
node.prev = t; //设置新入队节点的pre指针指向原尾部节点
if (compareAndSetTail(t, node)) { //使用CAS更新尾部节点,将当前节点设置成尾节点
t.next = node; //将原尾部节点next指针指向当前节点(新的尾节点)
return t;
}
}
}
}
//获取锁失败,入队后, 队列中循环尝试获取锁
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
//死循环,正常情况下线程只有获得锁才能跳出循环
for (;;) {
final Node p = node.predecessor();//获得当前线程所在结点的前驱结点
if (p == head && tryAcquire(arg)) { //如果前面的是头节点,可能头节点会释放锁,所以尝试获取锁
setHead(node); //将当前结点设置为队列头结点
p.next = null; // help GC
failed = false;
return interrupted;//正常情况下死循环唯一的出口
}
if (shouldParkAfterFailedAcquire(p, node) && //根据前1个节点的状态,判断是否要阻塞当前线程
parkAndCheckInterrupt()) //阻塞当前线程
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
/** waitStatus value to indicate thread has cancelled */
static final int CANCELLED = 1;
/** waitStatus value to indicate successor's thread needs unparking */
static final int SIGNAL = -1;
/** waitStatus value to indicate thread is waiting on condition */
static final int CONDITION = -2;
/**
* waitStatus value to indicate the next acquireShared should
* unconditionally propagate
*/
static final int PROPAGATE = -3;
//修改前驱节点状态
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
int ws = pred.waitStatus;
if (ws == Node.SIGNAL) //前驱节点状态为SIGNAL
return true; //阻塞当前线程
if (ws > 0) { //前驱节点状态为CANCELLED取消等待
do {
node.prev = pred = pred.prev;
} while (pred.waitStatus > 0);
pred.next = node; //找到前驱节点不是CANCELLED状态的
} else { //状态为初始化状态
//修改前驱节点的状态
compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
}
return false; //不堵塞当前线程,继续自旋
}
//线程阻塞
private final boolean parkAndCheckInterrupt() {
LockSupport.park(this); //当前线程阻塞
return Thread.interrupted(); //获取线程中断状态,并重置中断状态
}
解锁
public void unlock() {
sync.release(1);
}
public final boolean release(int arg) {
if (tryRelease(arg)) { //释放锁,当重入次数为0,可被其他线程获取,返回true
Node h = head;
if (h != null && h.waitStatus != 0) //当前队列不为空且头结点状态不为初始化状态(0)
unparkSuccessor(h); //唤醒同步队列中被阻塞的线程
return true;
}
return false;
}
protected final boolean tryRelease(int releases) {
int c = getState() - releases; //重入次数减1
if (Thread.currentThread() != getExclusiveOwnerThread()) //如果当前线程不是持有锁的线程,抛异常
throw new IllegalMonitorStateException();
boolean free = false;
if (c == 0) { //待更新的state值为0,说明持有锁的线程未重入,一旦释放锁其他线程将能获取
free = true;
setExclusiveOwnerThread(null); //清除锁的持有线程标记
}
setState(c);
return free;
}
private void unparkSuccessor(Node node) {
int ws = node.waitStatus;
if (ws < 0)
compareAndSetWaitStatus(node, ws, 0); //头节点WaitStatus设置成默认值
/*
* Thread to unpark is held in successor, which is normally
* just the next node. But if cancelled or apparently null,
* traverse backwards from tail to find the actual
* non-cancelled successor.
*/
Node s = node.next;
if (s == null || s.waitStatus > 0) { // 如果后续节点不存在或者后续节点的状态为CANCELLED,就继续查找
s = null;
for (Node t = tail; t != null && t != node; t = t.prev)
if (t.waitStatus <= 0) //从尾部遍历直到找到最后1个符合条件的节点
s = t;
}
if (s != null)
LockSupport.unpark(s.thread); //唤醒节点
}