队列里面添加一个结点 添加到队列的后面
private Node addWaiter(Node mode) {
// 构造一个结点
Node node = new Node(Thread.currentThread(), mode);
// Try the fast path of enq; backup to full enq on failure
// 尾结点
Node pred = tail;
if (pred != null) {
node.prev = pred;
// cas 设置尾结点
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
// 如果尾结点为空 y也就是第一次的时候才会执行到这里
enq(node);
return node;
}
private Node enq(final Node node) {
for (;;) {
// 重新获取尾结点
Node t = tail;
if (t == null) { // Must initialize
尾结点如果是空的话 设置一个空的 `头结点`
if (compareAndSetHead(new Node()))
// 尾结点 = 头结点
tail = head;
} else {
和上面一样 cas 设置 `尾结点` 为尾结点 也就是头结点的后一个
node.prev = t;
if (compareAndSetTail(t, node)) {
t.next = node;
return t;
}
}
}
}
尝试获取锁 公平锁
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
// 0为默认状态
if (c == 0) {
如果持有锁的不是当前线程 && cas成功 && 设置锁的持有者为当前线程
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
// 持有锁的就是当前线程
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
// 线程的状态 state++ 可重入锁
setState(nextc);
return true;
}
// 其他的情况 队列为空 或者 获取锁失败 ...
return false;
}
true 如果有当前线程前面的线程排队
false 如果当前线程是在队列的头部或队列为空
public final boolean hasQueuedPredecessors() {
// The correctness of this depends on head being initialized
// before tail and on head.next being accurate if the current
// thread is first in queue.
Node t = tail; // Read fields in reverse initialization order
Node h = head;
Node s;
头结点 != 尾节点 && 头结点的后一个不能为空 && 当前持有锁的线程不是当前线程
-> `头结点的后一个结点 是当前线程 false 取反 去尝试获取锁`
-> `队列为空 或者 头结点的后一个结点 不是当前线程 true 取反 不去尝试获取锁`
return h != t && ((s = h.next) == null || s.thread != Thread.currentThread());
}
public final boolean release(int arg) {
// 尝试释放锁
if (tryRelease(arg)) {
// 如果完全释放
Node h = head;
// 如果头结点不为空 并且 状态不为0
if (h != null && h.waitStatus != 0)
// 唤醒后续结点
unparkSuccessor(h);
// 返回解锁成功
return true;
}
return false;
}
重入锁未解锁完成 返回false
protected final boolean tryRelease(int releases) {
// 锁的状态 -1
int c = getState() - releases;
// 如果当前线程不是 锁的持有者 抛个异常
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
// 如果 c == 0 说明当前这个锁 重入的 都已经释放完了
boolean free = false;
if (c == 0) {
free = true;
// 设置当前持有锁的线程 为 null
setExclusiveOwnerThread(null);
}
// 最后更新锁的状态 直接进行更新 并放到最后
setState(c);
// 最后返回当前锁 是否被完全释放
return free;
}
唤醒后续结点 node 头结点
private void unparkSuccessor(Node node) {
/*
* If status is negative (i.e., possibly needing signal) try
* to clear in anticipation of signalling. It is OK if this
* fails or if status is changed by waiting thread.
*/
// 如果小于0 安全状态
int ws = node.waitStatus;
if (ws < 0)
// 设置头结点状态 为 0
compareAndSetWaitStatus(node, ws, 0);
/*
* 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) {
s = null;
// 从尾结点开始 倒着往前找 到 head 为止 找到一个 状态 为 -1 的node 节点
for (Node t = tail; t != null && t != node; t = t.prev)
if (t.waitStatus <= 0)
相当于从前往后找第一个 state = -1 的node
s = t;
}
// 如果存在 一个node 的状态 == -1 或者 <0 直接唤醒
if (s != null)
LockSupport.unpark(s.thread);
}
非公平锁
非公平锁
/**
* Performs lock. Try immediate barge, backing up to normal
* acquire on failure.
*/
final void lock() {
进来直接cas 不成功 执行 acquire
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
// 和 公平锁一样 不同的是重写了 tryAcquire 方法 直接使用 sync 的 非公平尝试
acquire(1);
}
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}