ReentrantLock可重入锁原理解析
作者:lane
这篇文章主要为大家介绍了ReentrantLock可重入锁原理解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
ReentrantLock 可重入锁
字面意思理解为同一线程可以重入加锁
内部主要逻辑继承AQS来实现的,有两种实现FairSycn、NonfairSync,公平锁和非公平锁,默认为非公平锁。
- 公平锁:保证先入队的先获得锁。
- 非公平锁:不保证先入队的先获得锁,可能后面的线程先抢到锁。

主要实现流程

CAS全名compare and swap比较交换,由native方法提供的系统原子性操作,以保证并发发安全性。
公平锁的实现
加锁
//加锁
final void lock() {
acquire(1);//调用AQS方法
}//AQS方法
public final void acquire(int arg) {
if (!tryAcquire(arg) &&//尝试获取锁,抽象方法由子类实现
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
/* addWaiter 将线程加入等待队列
* acquireQueued 尝试获取锁、阻塞
*/
{
//中断
selfInterrupt();
}
}//尝试获取锁
protected final boolean tryAcquire(int acquires) {
//获取当前线程
final Thread current = Thread.currentThread();
int c = getState();//获取state值,AQS属性volatile标记
if (c == 0) {//锁空闲状态
if (!hasQueuedPredecessors() &&//是否需要排队
compareAndSetState(0, acquires)) {//获取锁
setExclusiveOwnerThread(current);//成功获取,设置锁owner为当前线程
return true;//后续不在处理
}
}
else if (current == getExclusiveOwnerThread()) {//当前线程已持有锁,重入
int nextc = c + acquires;//state+1
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);//已持有锁,直接设置state值
return true;
}
return false;
}解锁
//解锁,ReentrantLock方法
public void unlock() {
sync.release(1);//AQS方法
}//AQS解锁
public final boolean release(int arg) {
if (tryRelease(arg)) {//尝试解锁
Node h = head;
if (h != null && h.waitStatus != 0)//waitStatus=0时不进行unpark(唤醒),next线程可能中断
unparkSuccessor(h);//唤醒队列中的线程去获取锁
return true;
}
return false;
}//尝试解锁ReentrantLock内部静态类Sync实现
protected final boolean tryRelease(int releases) {
int c = getState() - releases;//state-1
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();//非持有锁的线程进行释放,非法操作
boolean free = false;
if (c == 0) {//持有锁线程全部释放
free = true;
setExclusiveOwnerThread(null);//持有锁线程置空
}
setState(c);//持有锁线程直接设置state
return free;
}非公平锁的实现
非公平锁和公平锁的核心区别是在尝试获取锁方法tryAcquire实现中没有判断hasQueuedPredecessors()是否需要排队,其他逻辑和公平锁是一致的。

以上就是ReentrantLock可重入锁原理解析的详细内容,更多关于ReentrantLock可重入锁的资料请关注脚本之家其它相关文章!
