1.ReentrantLock.unlock()分析
(1)首先嘗試釋放鎖,如果要求釋放數等于鎖狀態數,那么將鎖狀態位清0,清除鎖所有者,返回true;否則返回false;
(2)如果(1)返回的是true,說明鎖完全釋放。接下來將檢查等待隊列,并選擇一個waitStatus處于等待狀態的節點下的線程unpark(恢復),選擇的依據是從尾節點開始,選取最靠近頭節點的等待節點,同時清理隊列中線程被取消的節點;
(3)如果(1)返回false,說明鎖只是部分釋放,當前線程仍舊持有該鎖;
1
java.util.concurrent.locks.ReentrantLock
2
public void unlock() {
3
sync.release(1);
4
}
5
6
java.util.concurrent.locks.AbstractQueuedSynchronizer
7
public final boolean release(int arg) {
8
if (tryRelease(arg)) {
9
Node h = head;
10
if (h != null && h.waitStatus != 0)
11
unparkSuccessor(h);
12
return true;
13
}
14
return false;
15
}
16
17
18
protected final boolean tryRelease(int releases) {
19
int c = getState() - releases; //重入鎖加鎖的次數-釋放數量
20
if (Thread.currentThread() != getExclusiveOwnerThread()) //判斷獨占鎖是否為當前線程所有
21
throw new IllegalMonitorStateException();
22
boolean free = false;
23
if (c == 0) { //加鎖次數=釋放數量
24
free = true;
25
setExclusiveOwnerThread(null); //清除鎖擁有者標識
26
}
27
setState(c); //設置加鎖狀態
28
return free;
29
}
30
31
32
/**
33
* Wakes up node's successor, if one exists.
34
*
35
* @param node the node
36
*/
37
private void unparkSuccessor(Node node) {
38
/*
39
* Try to clear status in anticipation of signalling. It is
40
* OK if this fails or if status is changed by waiting thread.
41
*/
42
compareAndSetWaitStatus(node, Node.SIGNAL, 0); //清除頭節點signal狀態
43
44
/*
45
* Thread to unpark is held in successor, which is normally
46
* just the next node. But if cancelled or apparently null,
47
* traverse backwards from tail to find the actual
48
* non-cancelled successor.
49
*/
50
Node s = node.next;
51
if (s == null || s.waitStatus > 0) { //等待隊列喚醒的競爭滿足FIFO,本段代碼主要是尋找最靠近頭節點的,且waitStatus為signal、condition的鏈表節點
52
s = null;
53
for (Node t = tail; t != null && t != node; t = t.prev)
54
if (t.waitStatus <= 0)
55
s = t;
56
}
57
if (s != null)
58
LockSupport.unpark(s.thread);
59
}

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

58

59
