java源码阅读---ReentrantLock源码解析
ReentrantLock源码解读
在讲ReentrantLock之前我们先看一下Lock接口里的方法
Lock接口中的方法
lock()方法
void lock(); //直接加锁,如果加锁失败什么也不返回
lockInterruptibly()方法
void lockInterruptibly() throws InterruptedException;
lockInterruptibly()方法能够中断等待获取锁的线程。当两个线程同时通过lock.lockInterruptibly()获取某个锁时,假若此时线程A获取到了锁,而线程B只有等待,那么对线程B调用threadB.interrupt()方法能够中断线程B的等待过程。
tryLock()
boolean tryLock(); //直接加锁,如果加锁失败返回false
tryLock(long time, TimeUnit unit)
boolean tryLock(long time, TimeUnit unit) throws InterruptedException; // 尝试获取锁,如果没获取到锁,就等待一段时间,这段时间内还没获取到锁就返回false
unlock()方法
void unlock();//释放锁
newCondition()
Condition newCondition();// 条件锁
以上就是Lock接口中的方法,接下来我们看一下ReentrantLock的实现代码。
ReentrantLock的内部类
首先是ReentrantLock的三个内部类:Sync、NonfairSync、FairSync,其中NonfairSync类和FairSync类是继承Sync类
Sync类
首先Sync是一个静态的抽象类,下面我们看一下它的内部方法。
lock()
abstract void lock(); //抽象方法由子类实现
nonfairTryAcquire()
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {//判断当前是否有线程持有锁
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); //锁重入了,修改state的值
return true;
}
return false;
}
tryRelease()
释放锁的方法
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;
}
isHeldExclusively()
判断锁是否是当前线程持有
protected final boolean isHeldExclusively() {
// While we must in general read state before owner,
// we don't need to do so to check if current thread is owner
return getExclusiveOwnerThread() == Thread.currentThread();
}
newCondition()
// 条件锁
final ConditionObject newCondition() {
return new ConditionObject();
}
getOwner()
返回当前持有锁的线程,如果没有则返回null
final Thread getOwner() {
return getState() == 0 ? null : getExclusiveOwnerThread();
}
getHoldCount()
当前线程持有此锁的次数,如果当前线程不持有此锁,则为零
final int getHoldCount() {
return isHeldExclusively() ? getState() : 0;
}
NonfairSync类
NonfairSync是非公平锁的实现类,继承了Sync类。
lock()
加锁方法,因为是非公平锁所以在加锁的时候会先去尝试加锁,如果加锁失败则调用acquire()方法放入队列排队
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
tryAcquire()
这里是调用父类的方法nonfairTryAcquire
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
FairSync类
FairSync公平锁的实现类
lock()
加锁方法
final void lock() {
acquire(1);//调用父类的方法加锁
}
tryAcquire()
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;
}
}
以上就是ReentrantLock的内部类了,接下来看一下构造方法
ReentrantLock的构造方法
无参构造方法
无参构造方法默认使用非公平锁
public ReentrantLock() {
sync = new NonfairSync();
}
有参构造
传入参数为true时,是公平锁,false是非公平锁
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
ReentrantLock的其他方法
其他方法的调用主要主要看ReentrantLock使用的是公平锁还是非公平锁,这里就不一一介绍了;关于ReentrantLock的锁的实现还涉及到了AbstractQueuedSynchronizer、AbstractOwnableSynchronizer这两个类,这些我们后面再继续分析。