ReentrantLock底层依赖AQS进行实现,是一种可重入的锁。
在ReentrantLock中实现公平锁和非公平锁。
在公平锁中,当调用lock方法,会先判断队列是否存在等待中的节点,如果队列无节点,会尝试去获取锁,如果获取到了锁,则执行业务代码,如果获取不到锁,一般是因为存在锁竞争,则会将当前线程Node加入到AQS中队列的尾部,同时,当前线程会被中断(调用线程interrupt方法)。
在非公平锁中,当调用了lock方法,会先尝试去获取锁,如果可以获取锁,则直接执行业务代码,如果获取不到锁,则和公平锁一样,将node节点加入到线程尾部,同时,中断当前线程。
公平锁和非公平锁【不同点】就是:非公平锁会在lock发生的时候尝试获取锁,而公平锁会直接加入队列尾部。
当调用了unLock方法的时候,内部会调用release方法,该方法会将当前node的下一个node节点唤醒。
以下是对ReentrantLock源码的解析
公平锁
FairSync部分源码解析,FairSync是ReentrantLock的内部类,是对公平锁的实现
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
final void lock() {
//调用父类的方法,最终会调用到tryAcquire方法,父类方法中还会有获取锁失败后,加队列节点的操作
acquire(1);
}
/**
* 尝试去获取锁
*/
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
//如果state = 0,说明当前没有线程占用锁
if (c == 0) {
//当队列中不存在任何node,然后去尝试设置state的值
//就是说,在公平锁中,必须要队列中没有node,才会在一开始就获取锁,否则,不会去获取锁
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;
}
}
NofairSync部分源码解析,NofairSync是ReentrantLock的内部类,是对非公平锁的实现,NofairSync继承自Sync,Sync继承自AQS
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
/**
* 尝试获取锁
*/
final void lock() {
//在非公平锁中,会先通过cas尝试获取锁
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
//该方法是父类的方法
return nonfairTryAcquire(acquires);
}
}
Sync部分源码解析,对nonfairTryAcquire方法的描述
/**
* 非公平锁尝试获取锁
* @param acquires 操作数,在ReentrantLock中为1
* @return
*/
final boolean nonfairTryAcquire(int acquires) {
//当前线程
final Thread current = Thread.currentThread();
//获取AQS的state状态
int c = getState();
//当state为0,说明可以通过cas尝试获取锁
if (c == 0) {
//通过cas尝试获取锁
if (compareAndSetState(0, acquires)) {
//当cas成功,则将线当前线程设置为独占线程
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;
}
标签:return,ReentrantLock,获取,线程,公平,简单,final,acquires
From: https://blog.csdn.net/sjdxx/article/details/142755322