基于AQS实现的可重入锁,包括公平和非公平两种实现方式。
公平与非公平的差异:
1、非公平:主动抢锁,抢锁失败,进入AQS实现的获取锁流程(排队去)
2、公平锁:不主动抢锁,直接进入AQS的获取锁方法(排队去),这也是公平与非公平锁(主动尝试抢锁)的区别
可重入主要体现在对同一线程访问资源时,对资源state的值叠加
public class ReentrantLock implements Lock, java.io.Serializable {
//提供所有实现机制的同步器
private final Sync sync;
/**
* 继承至AQS的同步器基础类,子类分公平和非公平实现。用AQS的state表示获取锁资源的数量
*/
abstract static class Sync extends AbstractQueuedSynchronizer {
//获取锁的抽象方法,由子类具体实现
abstract void lock();
//非公平锁获取锁的方法
final boolean nonfairTryAcquire(int acquires) {
//获取当前线程
final Thread current = Thread.currentThread();
//获取AQS的state值
int c = getState();
//尝试获取锁
if (c == 0) {
//cas继续尝试获取
if (compareAndSetState(0, acquires)) {
//获取成功,设置获取到互斥锁的当前线程
setExclusiveOwnerThread(current);
return true;
}
}
//如果没有锁资源,则判断当前锁线程是否就是自己,如果是则进入方法,这块是可重入思想的主要实现
else if (current == getExclusiveOwnerThread()) {
//注意:这里分支块为啥没有CAS呢?因为进入这个方法时,当前线程算是重入,这就证明已经是加过互斥锁的,不存在竞争问题
//用AQS的state记录可重入次数
int nextc = c + acquires;
if (nextc < 0) // 超出int范围,超出会变成负数
throw new Error("Maximum lock count exceeded");
setState(nextc); //设置AQS state值
return true;
}
return false;
}
//释放锁资源的方法(不区分公平与非公平方式)
protected final boolean tryRelease(int releases) {
int c = getState() - releases; //用原state减去释放的资源值
if (Thread.currentThread() != getExclusiveOwnerThread())
//当前释放资源的线程并不是获取锁的线程,抛出异常
throw new IllegalMonitorStateException();
boolean free = false;
if (c == 0) { //完全释放成功,其他线程可以获取锁了
free = true;
setExclusiveOwnerThread(null);
}
setState(c); //更新state值
return free;
}
//判断是否获取到锁
protected final boolean isHeldExclusively() {
return getExclusiveOwnerThread() == Thread.currentThread();
}
//创建条件对象
final ConditionObject newCondition() {
return new ConditionObject();
}
//拿到获取锁的线程
final Thread getOwner() {
return getState() == 0 ? null : getExclusiveOwnerThread();
}
//获取锁资源数量(可重入次数)
final int getHoldCount() {
return isHeldExclusively() ? getState() : 0;
}
final boolean isLocked() {
return getState() != 0;
}
/**
* Reconstitutes the instance from a stream (that is, deserializes it).
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
setState(0); // reset to unlocked state
}
}
//实现非公平锁的同步器
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
/**
* Performs lock. Try immediate barge, backing up to normal
* acquire on failure.
*/
//获取锁方法
final void lock() {
//CAS设置state值,意为抢锁
if (compareAndSetState(0, 1))
//抢锁成功,设置互斥锁拥有线程为当前线程
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1); //抢锁失败,进入AQS实现的获取锁流程
}
protected final boolean tryAcquire(int acquires) {
//调用父类提供的非公平锁获取方法
return nonfairTryAcquire(acquires);
}
}
//实现公平锁的同步器
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
final void lock() {
//不主动抢锁,直接进入AQS的获取锁方法,这也是公平与非公平锁(主动尝试抢锁)的区别
acquire(1);
}
//获取锁的实现,给AQS调用的勾子函数的子类实现方法
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
//没有其他线程上锁,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;
}
}
//默认构造函数,创建的是非公平锁同步器
public ReentrantLock() {
sync = new NonfairSync();
}
//根据fair来创建公平和非公平锁同步器
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
//锁操作,调用sync同步器lock方法
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);
}
//获取AQS条件对象
public Condition newCondition() {
return sync.newCondition();
}
}