在
前面一节
中,我们分析了ReentrantLock.lock()方法,接下来我们接着分析ReentrantLock.unlock()方法。
1.ReentrantLock.unlock()分析
(1)首先尝试释放锁,如果要求释放数等于锁状态数,那么将锁状态位清0,清除锁所有者,返回true;否则返回false;
(2)如果(1)返回的是true,说明锁完全释放。接下来将检查等待队列,并选择下一个节点恢复(该节点必须是waitStatus),
如果该节点不存在或者被取消,则选择从尾节点开始,选取最靠近头节点的等待节点,同时清理队列中线程被取消的节点;
大家回忆下lock()实现机制,新节点是从尾部插入的。这就说明AQS里面的 CLH其实是一个FIFO队列(用双链表实现的FIFO队列).
(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
