ReentrantLock 源码分析 - 解锁
SunRan

release

1
2
3
4
5
6
7
8
9
10
11
12
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;
}

tryRelease

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@ReservedStackAccess
protected final boolean tryRelease(int releases) {
// 先判断锁计数器
int c = getState() - releases;
// 是否是当前线程持有锁
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
// 默认返回的是false
boolean free = false;
// 如果锁计数器为0 表示重入锁全部解锁
if (c == 0) {
// 设置为true
free = true;
// 设置锁所有人为空
setExclusiveOwnerThread(null);
}
// 设置锁状态
setState(c);
return free;
}

unparkSuccessor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private void unparkSuccessor(Node node) {
// 如果当前节点状态 为-1 -2 -3 则通过比较替换为0
int ws = node.waitStatus;
if (ws < 0)
compareAndSetWaitStatus(node, ws, 0);

Node s = node.next;
// 如果下个节点是null或者下个节点被cancelled
// 就链表一直往下找,直至找到状态小于等同于0
if (s == null || s.waitStatus > 0) {
s = null;
for (Node t = tail; t != null && t != node; t = t.prev)
if (t.waitStatus <= 0)
s = t;
}
// 如果当前节点的下个节点不为空,而且状态<=0,就把当前节点unpark
if (s != null)
LockSupport.unpark(s.thread);
}

  • 本文标题:ReentrantLock 源码分析 - 解锁
  • 本文作者:SunRan
  • 创建时间:2022-01-06 15:51:42
  • 本文链接:https://lksun.cn/2022/01/06/ReentrantLock 源码分析 - 解锁/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
 评论