Skip to content

Commit 16372ec

Browse files
committed
重入锁
1 parent 86d48f2 commit 16372ec

File tree

1 file changed

+87
-1
lines changed

1 file changed

+87
-1
lines changed

MD/ReentrantLock.md

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,90 @@
44

55
`ReentrantLock` 就是一个普通的类,它是基于 `AQS(AbstractQueuedSynchronizer)`来实现的。
66

7-
> `AQS``Java` 并发包里实现锁、同步的一个基础框架。
7+
> `AQS``Java` 并发包里实现锁、同步的一个基础框架。
8+
9+
10+
## 锁类型
11+
12+
ReentrantLock 分为**公平锁****非公平锁**,可以通过构造方法来指定具体类型:
13+
14+
```java
15+
//默认非公平锁
16+
public ReentrantLock() {
17+
sync = new NonfairSync();
18+
}
19+
20+
//公平锁
21+
public ReentrantLock(boolean fair) {
22+
sync = fair ? new FairSync() : new NonfairSync();
23+
}
24+
```
25+
26+
默认一般使用**非公平锁**,它的效率和吞吐量都比公平锁高的多(后面会分析具体原因)。
27+
28+
## 获取锁
29+
30+
通常的使用方式如下:
31+
32+
```java
33+
private ReentrantLock lock = new ReentrantLock();
34+
public void run() {
35+
lock.lock();
36+
try {
37+
//do bussiness
38+
} catch (InterruptedException e) {
39+
e.printStackTrace();
40+
} finally {
41+
lock.unlock();
42+
}
43+
}
44+
```
45+
46+
### 公平锁获取锁
47+
首先看下获取锁的过程:
48+
49+
```java
50+
public void lock() {
51+
sync.lock();
52+
}
53+
```
54+
55+
可以看到是使用 `sync`的方法,而这个方法是一个抽象方法,具体是由其子类(`FairSync`)来实现的,以下是公平锁的实现:
56+
57+
```java
58+
final void lock() {
59+
acquire(1);
60+
}
61+
62+
//AbstractQueuedSynchronizer 中的 acquire()
63+
public final void acquire(int arg) {
64+
if (!tryAcquire(arg) &&
65+
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
66+
selfInterrupt();
67+
}
68+
```
69+
70+
第一步是尝试获取锁(`tryAcquire(arg)`),这个也是由其子类实现:
71+
72+
```java
73+
protected final boolean tryAcquire(int acquires) {
74+
final Thread current = Thread.currentThread();
75+
int c = getState();
76+
if (c == 0) {
77+
if (!hasQueuedPredecessors() &&
78+
compareAndSetState(0, acquires)) {
79+
setExclusiveOwnerThread(current);
80+
return true;
81+
}
82+
}
83+
else if (current == getExclusiveOwnerThread()) {
84+
int nextc = c + acquires;
85+
if (nextc < 0)
86+
throw new Error("Maximum lock count exceeded");
87+
setState(nextc);
88+
return true;
89+
}
90+
return false;
91+
}
92+
}
93+
```

0 commit comments

Comments
 (0)