Skip to content

Commit dd638ed

Browse files
committed
重入锁
1 parent e36ac97 commit dd638ed

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed

MD/ReentrantLock.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,5 +224,75 @@ ReentrantLock 分为**公平锁**和**非公平锁**,可以通过构造方法
224224
}
225225
```
226226

227+
还要一个重要的区别是在尝试获取锁时`tryAcquire(arg)`,非公平锁是不需要判断队列中是否还有其他线程,也是直接尝试获取锁:
228+
229+
```java
230+
final boolean nonfairTryAcquire(int acquires) {
231+
final Thread current = Thread.currentThread();
232+
int c = getState();
233+
if (c == 0) {
234+
//没有 !hasQueuedPredecessors() 判断
235+
if (compareAndSetState(0, acquires)) {
236+
setExclusiveOwnerThread(current);
237+
return true;
238+
}
239+
}
240+
else if (current == getExclusiveOwnerThread()) {
241+
int nextc = c + acquires;
242+
if (nextc < 0) // overflow
243+
throw new Error("Maximum lock count exceeded");
244+
setState(nextc);
245+
return true;
246+
}
247+
return false;
248+
}
249+
```
250+
251+
## 释放锁
252+
253+
公平锁和非公平锁的释放流程都是一样的:
254+
255+
```java
256+
public void unlock() {
257+
sync.release(1);
258+
}
259+
260+
public final boolean release(int arg) {
261+
if (tryRelease(arg)) {
262+
Node h = head;
263+
if (h != null && h.waitStatus != 0)
264+
unparkSuccessor(h);
265+
return true;
266+
}
267+
return false;
268+
}
269+
270+
//尝试释放锁
271+
protected final boolean tryRelease(int releases) {
272+
int c = getState() - releases;
273+
if (Thread.currentThread() != getExclusiveOwnerThread())
274+
throw new IllegalMonitorStateException();
275+
boolean free = false;
276+
if (c == 0) {
277+
free = true;
278+
setExclusiveOwnerThread(null);
279+
}
280+
setState(c);
281+
return free;
282+
}
283+
```
284+
285+
首先会判断当前线程是否为获得锁的线程,由于是重入锁所以需要将 `state` 减到 0 才认为完全释放锁。
286+
287+
释放之后需要调用 `unparkSuccessor(h)` 来唤醒被挂起的线程。
288+
289+
290+
## 总结
291+
292+
由于公平锁需要关心队列的情况,得按照队列里的先后顺序来获取锁(会造成大量的线程上下文切换),而非公平锁则没有这个逻辑。
293+
294+
所以也就能解释非公平锁的效率会被公平锁更高。
295+
296+
227297

228298

0 commit comments

Comments
 (0)