ReentrantLock

很常用的一个锁

一、可重入原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//TODO acquireQueued方法还不算熟悉
//公平策略
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;

final void lock() {
//尝试抢占
acquire(1);
}
//tryAcquire返回false会进入
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
//加入一个新节点进入CLH
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}

//可重入原理:如果没人占有锁,就cas尝试占有,否则如果是当前线程,state++,
//会检查,由此可以看到嵌套的最大层数不能超过int,两者都失败会返回false,
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
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");
setState(nextc);
return true;
}
return false;
}
}

static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;

/**
* 很鲁莽,上来就想抢占锁,把自己设置为占有锁的线程,否则尝试抢占
*/
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}

protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}

二、Condition 的使用

1
//TODO

ReentrantLock
https://polarisink.github.io/20221010/yuque/ReentrantLock/
作者
Areis
发布于
2022年10月10日
许可协议