ReentrantLock源码分析

源码实现

类的继承关系

ReentrantLock实现了Lock接口,Lock接口定义了锁的通用方法。

1
public class ReentrantLock implements Lock, java.io.Serializable 

内部类

ReentrantLock内部有三个内部类,其中Sync是其它两个类NonfairSyncFairSync的父类,分别代表着非公平策略和公平策略。

Sync

继承自AbstractQueuedSynchronizer,实现了对state字段的修改操作。

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;

/**
* Performs {@link Lock#lock}. The main reason for subclassing
* is to allow fast path for nonfair version.
*/
abstract void lock();

/**
* Performs non-fair tryLock. tryAcquire is implemented in
* subclasses, but both need nonfair try for trylock method.
*/
//非公平方式尝试获取锁
final boolean nonfairTryAcquire(int acquires) {
//获取当前线程
final Thread current = Thread.currentThread();
//获取AQS的state状态
int c = getState();
//为0表示暂无线程占用锁
if (c == 0) {
//通过CAS设置state
if (compareAndSetState(0, acquires)) {
//设置成功之后,设置当前线程独占
setExclusiveOwnerThread(current);
return true;
}
}
//如果当前线程拥有锁,则表示进行重入
else if (current == getExclusiveOwnerThread()) {
//添加重入次数
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}

//尝试释放锁资源,全部释放则返回true
protected final boolean tryRelease(int releases) {
//c是释放后的资源量
int c = getState() - releases;
//如果当前线程不是占有锁的线程,抛出异常
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
//free是全部释放的标识
boolean free = false;
//如果c = 0,说明全部释放资源,可重入环境
if (c == 0) {
//设置全部释放标识
free = true;
//置空独占线程
setExclusiveOwnerThread(null);
}
setState(c);
return free;
}

//判断资源是否被当前线程占有
protected final boolean isHeldExclusively() {
// While we must in general read state before owner,
// we don't need to do so to check if current thread is owner
return getExclusiveOwnerThread() == Thread.currentThread();
}

//生成一个条件
final ConditionObject newCondition() {
return new ConditionObject();
}

// Methods relayed from outer class
//返回占用锁的线程
final Thread getOwner() {
return getState() == 0 ? null : getExclusiveOwnerThread();
}
//如果锁被线程占有,则返回state
final int getHoldCount() {
return isHeldExclusively() ? getState() : 0;
}

//判断锁是否被线程占有
//state不等于0则锁被线程占用
final boolean isLocked() {
return getState() != 0;
}

//自定义反序列化逻辑
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
setState(0); // reset to unlocked state
}
}

NonfairSync

NonfairSync表示是非公平策略获取锁。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;

//获得锁
final void lock() {
//CAS操作设置state为1
if (compareAndSetState(0, 1))
//CAS设置成功,则设置独占进程为当前进程
setExclusiveOwnerThread(Thread.currentThread());
else
//锁已经被占用,或者set失败
//独占方式进行获取
acquire(1);
}

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

FairSync

采用公平策略获取锁。

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
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
//调用acquire方法,以独占方式获取锁
final void lock() {
acquire(1);
}

//尝试获取公平锁
protected final boolean tryAcquire(int acquires) {
//获取当前线程
final Thread current = Thread.currentThread();
//获取AQS的state
int c = getState();
//如果当前没有线程占有锁
if (c == 0) {
//判断AQS Queue是否有线程在等待
//如果没有则直接通过CAS获取锁资源
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;
}
}

成员变量

sync代表当前ReentrantLock使用的获取策略。

1
2
private final Sync sync;
private static final long serialVersionUID = 7373984872572414699L;

构造方法

  • 无参构造方法
    • 默认是非公平策略
  • 有参构造方法
    • 传入true使用公平策略。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* Creates an instance of {@code ReentrantLock}.
* This is equivalent to using {@code ReentrantLock(false)}.
*/
public ReentrantLock() {
sync = new NonfairSync();
}

/**
* Creates an instance of {@code ReentrantLock} with the
* given fairness policy.
*
* @param fair {@code true} if this lock should use a fair ordering policy
*/
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}

核心方法

lock

调用sync.lock()

1
2
3
public void lock() {
sync.lock();
}

lockInterruptibly

响应中断的获取锁的方法,调用AQS.acquireInterruptibly()完成。

1
2
3
4
5
6
7
8
9
10
11
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}

public final void acquireInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (!tryAcquire(arg))
doAcquireInterruptibly(arg);
}

tryLock

非公平方式尝试获取锁,调用sync.nonfairTryAcquire(1)完成。重载方法提供了超时策略,同时响应中断。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public boolean tryLock() {
return sync.nonfairTryAcquire(1);
}

public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}

public final boolean tryAcquireNanos(int arg, long nanosTimeout)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
return tryAcquire(arg) ||
doAcquireNanos(arg, nanosTimeout);
}

unlock

调用sync.release(1)完成unlock()操作。

1
2
3
public void unlock() {
sync.release(1);
}

总结

ReentrantLock的核心功能主要通过内部类Sync完成。而Sync继承自AQS,通过AQS中的Sync Queue完成对线程排队的功能。ReentrantLock的公平策略和非公平策略通过另外两个内部类FairSyncNonfairSync实现。