总结:
ReentrantLock是一把可重入的独占锁,即一把同一时刻只允许一个线程拥有的写锁,虽然只允许一个线程同时持有,但是没有限制一个线程持有次数。ReentrantLock用两个变量来表示锁资源{锁持有计数(state),锁拥有者(owner)},state不为0就表示有人持有了锁,然后再判断owner是不是自己,如果是则说明是自己获得了锁,允许再次获得锁,反之不允许
import java.util.concurrent.TimeUnit;
import java.util.Collection;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
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;
//sync是基类,从此基础上会派生出公平和非公平方式
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;
//分公平和非公平方式,所以是抽象方法
abstract void lock();
//非公平方式的获取独占锁tryAcquire,acquires参数为1
final boolean nonfairTryAcquire(int acquires) {
//获取当前线程,可重入的独占锁,所以要记录锁拥有者
final Thread current = Thread.currentThread();
//获取锁状态,state表示获取了几次锁
int c = getState();
//快速判断一下是否有人获取了锁,0表没人
if (c == 0) {
//如果没人获取锁,则尝试通过cas抢占锁
if (compareAndSetState(0, acquires)) {
//如果抢占成功,则记录锁的拥有者为当前线程
setExclusiveOwnerThread(current);
return true;
}
}
//不为0表有人已经获得了锁,所以就判断是不是自己获得了锁
else if (current == getExclusiveOwnerThread()) {
//如果是自己获得了锁,则锁计数+acquires,这里acquires=1
int nextc = c + acquires;
//如果计数超过了int_max就表示获取锁次数太多了
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
//这里设置state,不需要使用cas,因为此时本线程已经获得了锁,是重入
setState(nextc);
return true;
}
//否则走到这里表明有人获得了锁,且不是自己就返回获取锁失败
return false;
}
//tryRelease:释放锁资源,释放锁资源没有公平不公平一说
protected final boolean tryRelease(int releases) {
//释放锁资源就是锁计数-releases,releases这里等于1
int c = getState() - releases;
//如果不是自己拥有锁,就抛异常,因为必须拥有锁才能释放
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
//如果释放后计数归0,则表明本线程已释放全部锁
if (c == 0) {
free = true;
//所以把锁的拥有者设置为null
setExclusiveOwnerThread(null);
}
//注意,此时state还是不为0的,所以也就是说其他线程看到的state不为0
//也就是说当前线程还拥有锁,所以可以无保护设置
setState(c);
return free;
}
//判断是不是自己获得了锁
//这里无需锁保护(暂时不太懂)
protected final boolean isHeldExclusively() {
return getExclusiveOwnerThread() == Thread.currentThread();
}
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;
}
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;
//非公平lock:就是在入队之前就检测一次能否获得锁,如果能,就直接获取锁而不用入队排队等待
final void lock() {
//快速尝试能否获得锁:如果state状态为0,并且本线程成功通过cas设置state,则成功获得所
if (compareAndSetState(0, 1))
//成功获得锁就设置一下锁拥有者为自己
setExclusiveOwnerThread(Thread.currentThread());
else
//如果快速获取失败,则走重逻辑获取锁:
// 先入队排队,直到本线程成为head.next,然后本线程再尝试获取锁
acquire(1);
}
//tryAcquire:就是对nonfairTryAcquire的简单封装
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
//公平方式获得锁:就是先排队,等他前面的都获得了锁,然后再轮到他
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
//就是直接调用aqs的acquire,把当前线程的node添加到sync list末尾,
// 直到本node成为head.next才开始尝试
final void lock() {
//注意:aqs的acquire函数一进去就会调用tryAcquire尝试快速获得锁
//所以为了实现公平锁:即先来先获取锁
//那么tryAcquire的逻辑必须是:如果检测到AQS的sync list中有线程在排队
//那么就直接返回false,也就是说只要有人在排队,后来者就获取锁失败
acquire(1);
}
//公平方式:如果有人排队就返回false
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
//先资源是否被人持有
if (c == 0) {
//如果锁空闲则判断有没有人在排队,如果有,则返回false
//hasQueuedPredecessor函数是不准确的
//也就是说可能在判断的时候有其他人刚好也判断并取了锁
//这个没关系的
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;
}
//否则返回false表示获取失败
return false;
}
}
public ReentrantLock() {
sync = new NonfairSync();
}
//创建ReentrantLock,默认非公平锁
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
//ReentrantLock.lock就是调用sync.lock
public void lock() {
sync.lock();
}
//获取锁,如果发生中断就抛异常
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
//ReentrantLock导出的tryLock方法,表示尝试获取锁,如果获取不到就直接返回false
//也就是说这里直接调用tryAcquire尝试获取锁,而tryAcquire是不会阻塞的
public boolean tryLock() {
return sync.nonfairTryAcquire(1);
}
//尝试获取锁,发生中断就抛异常,超时就返回false
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
//释放锁,前面说过了,就是锁计数-1,如果为0,就清空锁拥有者
public void unlock() {
sync.release(1);
}
//创建条件变量
public Condition newCondition() {
return sync.newCondition();
}
//判断当前线程获取锁的次数,如果不持有锁则为0
public int getHoldCount() {
return sync.getHoldCount();
}
//判断当前线程是有持有锁
public boolean isHeldByCurrentThread() {
return sync.isHeldExclusively();
}
//判断是否有人获取了锁(自己或者其他人)
public boolean isLocked() {
return sync.isLocked();
}
//是不是公平锁
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);
}
public String toString() {
Thread o = sync.getOwner();
return super.toString() + ((o == null) ?
"[Unlocked]" :
"[Locked by thread " + o.getName() + "]");
}
//总结下来就是ReentrantLock的condition就是直接用的AQS的condition
}