图1-1java
根据上图能够知道,ReenTrantLock继承了Lock接口,Lock接口声明方法以下:bash
方法名 | 说明 | 抛出异常 |
---|---|---|
lock() | 一直阻塞获取锁,直到获取成功 | 无 |
lockInterruptibly() | 尝试获取锁,直到获取锁或者线程被中断 | InterruptedException |
tryLock() | 尝试获取空闲的锁,获取成功返回true,获取失败返回false,不会阻塞,当即返回 | 无 |
tryLock(long time, TimeUnit unit) | 尝试在time时间内获取空闲的锁,在等待时间内能够被中断 | InterruptedException |
unlock() | 释放锁 | 无 |
newCondition() | 返回当前锁的一个condition实例,用于条件性等待 | 无 |
1.ReentrantLock的部分方法ui
图2-1spa
Sync是NonfairSync 和FairSync 的父类,声明方法以下:线程
/**
* 抽象方法,获取锁
*/
abstract void lock();
/**
* 实现非公平锁获取逻辑
*/
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState(); //父类同步器方法,获取当前同步状态,后续文章会分析
if (c == 0) {//状态等于0表示没有获取到锁
if (compareAndSetState(0, acquires)) { //CAS方式修改状态
setExclusiveOwnerThread(current); //修改为功后设置当前线程为锁的全部者
return true;
}
}
else if (current == getExclusiveOwnerThread()) {//当前锁已被占用,判断是否是本身获取到了锁,锁重入
int nextc = c + acquires; //获取锁的计数器
if (nextc < 0) // overflow //由于是int类型,若是超过int最大值会溢出为负
throw new Error("Maximum lock count exceeded");
setState(nextc);//设置计数器为状态值
return true;
}
return false;
}
protected final boolean tryRelease(int releases) {
int c = getState() - releases;//释放锁,同步状态减int值
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException(); //若是当前相差不是锁的拥有者,抛出异常
boolean free = false;
if (c == 0) { //若是同步状态值为0,表示锁已经释放成功
free = true;
setExclusiveOwnerThread(null); // 设置锁的拥有线程为null
}
setState(c);//从新赋值同步状态
return free;
}
//判断当前线程是否是锁独占
protected final boolean isHeldExclusively() {
return getExclusiveOwnerThread() == Thread.currentThread();
}
//返回锁的ConditionObject实例
final ConditionObject newCondition() {
return new ConditionObject();
}
// Methods relayed from outer class
//获取当前占有锁的线程
final Thread getOwner() {
return getState() == 0 ? null : getExclusiveOwnerThread();
}
//获取当前锁计数
final int getHoldCount() {
return isHeldExclusively() ? getState() : 0;
}
//判断是否获取到锁
final boolean isLocked() {
return getState() != 0; //能够知道判断获取锁的关键就是是否不等于0
}
复制代码
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() {
if (compareAndSetState(0, 1))//CAS获取锁
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
复制代码
lock()
和tryAcquire(int acquires)
方法,其中和tryAcquire(int acquires)
方法直接调用了父类的nonfairTryAcquire(acquires)
,介绍父类的时候已经解析过,不清楚能够看上文Sync解析部分。根据lock源码发现,开始判断是不是第一次获取锁,若是获取锁成功,就把当前线程设置为锁的占有者,不然调用父类的acquire(1)
方法(下一篇介绍同步器会介绍)。static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
/**调用父类的acquire()方法*/
final void lock() {
acquire(1);
}
/**
* 尝试获取锁
*/
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;
}
}
复制代码
!hasQueuedPredecessors()
判断,其实该方法就是判断是否有比当前线程等待最长时间的线程,若是没有,那么就尝试获取锁,获取成功后设置当前线程为锁的占有者,因此,公平与不公平就是是否按照时间等待来获取锁的,好比食堂吃饭,排队一个个来,这就是公平,若是有人插队,这就是不公平。public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
public void lock() {
sync.lock();
}
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
public boolean tryLock() {
return sync.nonfairTryAcquire(1);
}
//指定超时时间内获取锁,阻塞时间为timeout
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
public Condition newCondition() {
return sync.newCondition();
}
public int getHoldCount() {
return sync.getHoldCount();
}
public boolean isHeldByCurrentThread() {
return sync.isHeldExclusively();
}
public final boolean isFair() {
return sync instanceof FairSync;
}
protected Thread getOwner() {
return sync.getOwner();
}
public final boolean hasQueuedThreads() {
return sync.hasQueuedThreads();
}
public final boolean hasQueuedThread(Thread thread) {
return sync.isQueued(thread);
}
public final int getQueueLength() {
return sync.getQueueLength();
}
protected Collection<Thread> getQueuedThreads() {
return sync.getQueuedThreads();
}
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);
}
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);
}
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);
}
复制代码
sync
,在介绍sync
时候已经说过,它就是继承了AbstractQueuedSynchronizer
同步器,不少方法都是直接调用父类同步器的方法,下一篇《java锁之ReentrantLock(二)》会重点解析AbstractQueuedSynchronizer
同步器源码,分析同步器是如何依托于FIFO队列完成锁的机制。