ReentrantLock
源码基于JDK8中的rt.jar下的java.util.concurrent.locks.ReentrantLock
此前写过一篇基于JDK14的,两份源码大致是一样的,只有个别方法有区别,而且仅仅是方法的名称有区别,实现的方式和具体的思想大致一样
对ReentrantLock源码的解读_JDK14
方法结构图
源码分析
package com.ramscy;
import java.util.Collection;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
public class ReentrantLock implements Lock, java.io.Serializable {
private static final long serialVersionUID = 7373984872572414699L;
private final Sync sync;
/**
* 继承自AQS的抽象静态内部类Sync
*/
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;
abstract void lock();
/**
* 获取当前线程对象,并尝试上锁
* 如果state状态值为0,则可以直接通过CAS操作上锁
* 如果state不为0,说明已经有线程持有锁
* 则需判断持有锁的线程是否是当前线程,如果是,则state值加1,否则尝试上锁失败
*
* @return
*/
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;
}
/**
* 尝试释放锁
* 如果当前线程是持有锁的线程,
* 且上锁次数和当前获得的state值(当前上锁次数)相同时,则可以成功释放锁
* ( 因为可能存在一种可能,传入的releases参数,在调用tryRelease方法时变化了,即同一个线程又获得了锁,
* state值增加了 )
* 否则,则释放掉releases层锁,设置state值为c = getState() - releases;
* 并返回false,释放锁失败
* @param releases
* @return
*/
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;
}
/**
* 判断当前线程是否是持有锁的线程
* @return
*/
protected final boolean isHeldExclusively() {
return getExclusiveOwnerThread() == Thread.currentThread();
}
/**
* 获取ConditionObject对象,ConditionObject继承自Condition
* @return
*/
final ConditionObject newCondition() {
return new ConditionObject();
}
/**
* 获取当前持有锁的线程
* @return
*/
final Thread getOwner() {
return getState() == 0 ? null : getExclusiveOwnerThread();
}
/**
* 如果当前线程是持有锁的线程,则获取当前可重入锁的state值,即上锁次数
* @return
*/
final int getHoldCount() {
return isHeldExclusively() ? getState() : 0;
}
/**
* 判断是否上锁,state值是否为0,为0则未上锁
* @return
*/
final boolean isLocked() {
return getState() != 0;
}
/**
* 设置state值为0,即无锁状态
* @param s
* @throws java.io.IOException
* @throws ClassNotFoundException
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
setState(0);
}
}
/**
* 非公平锁
*/
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
/**
* 重写了Sync父类的抽象方法lock()
* 与公平锁不同的是,这里先进行一次cas操作,如果成功,则直接设置当前线程为持有锁的线程
* 否则,在尝试获取锁
*/
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
/**
* 直接调用父类的方法
* @param acquires
* @return
*/
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
/**
* 公平锁
*/
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
/**
* 重写了父类的抽象方法lock(),尝试获取锁
*/
final void lock() {
acquire(1);
}
/**
* FairSync --> Sync --> AbstractQueuedSynchronizer
* 重写了AbstractQueuedSynchronizer父类的tryAcquire方法
* 尝试抢占锁
* @param acquires
* @return
*/
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
/**
* 与父类非公平锁实现的方法不同的地方,就是hasQueuedThreads方法
* 这个方法返回队列中是否有等待的线程,如果有则返回true
* 在这里的意思是,如果有等待的线程,返回true并取反,if条件无法执行
* 也即,无法让后来的线程插队,current就无法在正在队列中等待的线程之前获得锁
*/
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默认创建一个非公平锁对象
*/
public ReentrantLock() {
sync = new NonfairSync();
}
/**
* 有参构造方法
* 若传入参数为true,则为抽象静态内部类Sync创建一个公平锁对象
*/
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
/**
* ReentrantLock对象的lock接口调用lock方法,就是从这里开始的
* 底层,是调用了Sync类内部的lock方法
* lock方法调用步骤:reentrantlock对象调用lock方法 -> 到这里调用Sync的lock方法 ->
* Sync的lock方法是抽象方法,所以要调用子类(公平锁或非公平锁)重写的lock方法
* 如果是非公平锁,为了追求效率,会先进行一次cas操作,失败了才会尝试获取锁
* 通过至少调用一次tryAcquire方法并返回成功来实现。
* 否则,线程将排队,并可能反复阻塞和解除阻塞,并一直调用tryAcquire方法直到成功
*
* 公平锁的话,则是直接尝试获取锁,即直接调用acquire方法
*/
public void lock() {
sync.lock();
}
/**
* 调用父类Sync的lockInterruptibly方法
* Sync的lockInterruptibly方法是直接继承的AQS的方法
* @throws InterruptedException
*/
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
/**
* 调用sync对象中的nonfairTryAcquire方法
* @return
*/
public boolean tryLock() {
return sync.nonfairTryAcquire(1);
}
/**
* 调用sync对象中重载的tryLock方法
* tryAcquireNanos方法是直接继承自AQS的
* 多了一个超时放弃功能
* @param timeout
* @param unit
* @return
* @throws InterruptedException
*/
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
/**
* 尝试释放锁
*/
public void unlock() {
sync.release(1);
}
/**
* 获取Condition对象,调用了父类Sync的方法
* 底层是调用了AQS中的静态内部类ConditionObject的无参构造器
* ConditionObject继承了Condition类
* @return
*/
public Condition newCondition() {
return sync.newCondition();
}
/**
* 获取当前state值,也即上锁次数
* @return
*/
public int getHoldCount() {
return sync.getHoldCount();
}
/**
* 判断是否被当前线程上锁
* @return
*/
public boolean isHeldByCurrentThread() {
return sync.isHeldExclusively();
}
/**
* 判断是否上锁,即判断state值是否为0
* @return
*/
public boolean isLocked() {
return sync.isLocked();
}
/**
* 判断是否是公平锁
* @return
*/
public final boolean isFair() {
return sync instanceof FairSync;
}
/**
* 获取当前持有锁的线程
* @return
*/
protected Thread getOwner() {
return sync.getOwner();
}
/**
* 判断当前线程队列是否有正在等待的线程
* @return
*/
public final boolean hasQueuedThreads() {
return sync.hasQueuedThreads();
}
/**
* 判断当前线程队列中,是否存在某线程
* @param thread
* @return
*/
public final boolean hasQueuedThread(Thread thread) {
return sync.isQueued(thread);
}
/**
* 获取当前线程队列的长度
* @return
*/
public final int getQueueLength() {
return sync.getQueueLength();
}
/**
* 返回当前线程队列的集合,ArrayList
* @return
*/
protected Collection<Thread> getQueuedThreads() {
return sync.getQueuedThreads();
}
/**
* 如果传入的condition对象为null,则抛出NullPointerException异常
* 如果传入的对象不是AQS类下的内部类ConditionObject的实例对象或子类对象则抛出IllegalArgumentException异常
* <p>
* 否则调用AQS类下的hasWaiters方法,判断是否有正在等待的线程
* 但是由于超时和中断可能随时发生,因此并不能保证等待队列中的线程会被唤醒
* 此方法主要被设计用于监视系统状态
*
* @param condition
* @return
*/
public boolean hasWaiters(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
}
/**
* 获取等待队列的长度,即等待队列中等待线程的数量
* @param condition
* @return
*/
public int getWaitQueueLength(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
}
/**
* 获取等待队列中的正在等待的线程的ArrayList集合
* @param condition
* @return
*/
protected Collection<Thread> getWaitingThreads(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
}
public String toString() {
Thread o = sync.getOwner();
return super.toString() + ((o == null) ?
"[Unlocked]" :
"[Locked by thread " + o.getName() + "]");
}
}