ReentrantLock核心原理!
发表于更新于
ReentrantLock
是可重入的互斥锁。
ReentrantLock
底层基于AbstractQueuedSynchronizer
实现。
整体结构
ReentrantLock
内部定义了专门的组件Sync
,Sync
继承AbstractQueuedSynchronizer
提供释放资源的实现。
NonfairSync
和FairSync
是基于Sync
扩展的子类,即ReentrantLock
的非公平模式与公平模式。
它们作为Lock
接口功能的基本实现。

在ReentrantLock
中,它对AbstractQueuedSynchronizer
的state
状态值定义为线程获取该锁的重入次数。
state
状态值为0
表示当前没有被任何线程持有,state
状态值为1
表示被其他线程持有。
因为支持可重入,如果是持有锁的线程,再次获取同一把锁,直接成功,并且state
状态值+1
,线程释放锁state
状态值-1
。
同理重入多次锁的线程,需要释放相应的次数。
Sync
Sync
继承了AbstractQueuedSynchronizer
,是ReentrantLock
的核心,NonfairSync
与FairSync
都是基于Sync
扩展出来的子类。
Sync
实现了AQS
类的释放资源(tryRelease
),然后抽象了一个获取锁的函数(lock)让子类自行实现。
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
| abstract static class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = -5179523762034025860L;
abstract void lock();
final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (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; }
protected final boolean tryRelease(int releases) { int c = getState() - releases; if (Thread.currentThread() != getExclusiveOwnerThread()) throw new IllegalMonitorStateException(); boolean free = false; if (c == 0) { free = true; setExclusiveOwnerThread(null); } setState(c); return free; } }
|
tryRelease
流程:

NonfairSync
在ReentrantLock
中支持两种获取锁的策略,分别是非公平策略与公平策略,NonfairSync
就是非公平策略。
NonfairSync
继承Sync
实现了lock
函数,CAS
设置状态值state
为1
代表获取锁成功。
否则执行AQS
的acquire
函数(获取锁模板)。
另外NonfairSync
还实现了AQS
留给子类实现的tryAcquire
函数(获取资源)。
直接使用Sync
提供的nonfairTryAcquire
函数来实现tryAcquire
。
最后子类实现的tryAcquire
函数在AQS
的acquire
函数中被使用。
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
| static final class NonfairSync extends Sync { private static final long serialVersionUID = 7316153563782823691L;
final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); }
protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } }
public final void acquire(int arg) {
if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); }
|
当前线程查看资源是否可获取:
可获取,尝试使用CAS
设置state
为1
,CAS
成功代表获取资源成功,否则获取资源失败。
不可获取,判断当线程是不是持有锁的线程,如果是,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
|
final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (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; }
|
FairSync
FairSync
流程与NonfairSync
基本一致,唯一的区别就是在CAS
执行前,多了一步hasQueuedPredecessors
函数,这一步就是判断当前线程是不是CLH
队列被唤醒的线程,如果是就执行CAS
,否则获取资源失败。

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
| static final class FairSync extends Sync { private static final long serialVersionUID = -3000897897090466540L;
final void lock() { acquire(1); }
protected final boolean tryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { 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; } }
public final void acquire(int arg) {
if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); }
|
Lock的实现
1 2 3 4 5 6 7 8 9 10 11 12
| private final Sync sync;
public ReentrantLock() { sync = new NonfairSync(); }
public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); }
|
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
| public class ReentrantLock implements Lock, java.io.Serializable { private static final long serialVersionUID = 7373984872572414699L; private final Sync sync;
public ReentrantLock() { sync = new NonfairSync(); }
public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); }
public void lock() { sync.lock(); }
public void lockInterruptibly() throws InterruptedException { sync.acquireInterruptibly(1); }
public boolean tryLock() { return sync.nonfairTryAcquire(1); }
public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { return sync.tryAcquireNanos(1, unit.toNanos(timeout)); }
public void unlock() { sync.release(1); }
public Condition newCondition() { return sync.newCondition(); }
}
|