java.util.concurrent.locks.
ReentrantLock implements Lock, java.io.Serializable
ReentrantLock称为可重入锁,其内部可以分成两种锁,公平锁和非公平锁,均通过继承自一个父类Sync实现,该父类有继承自AQS类
1.类变量&常量
private final Sync sync; //提供所有实现机制的同步器
2.构造方法
//无参构造方法,默认构造一个非公平锁
public ReentrantLock() {
sync = new NonfairSync();
}
//有参构造方法,可以根据参数构造公平锁或非公平锁
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
3.重要方法
1.lock方法,调用sync的lock方法,实际使用时常用的加锁方式
public void lock() {
sync.lock();
}
2. tryLock方法,若未获得锁不会一直等待,而是返回false
public boolean tryLock() {
return sync.nonfairTryAcquire(1);
}
3. unlock方法,对锁的释放
public void unlock() {
sync.release(1);
}
4. isFair方法,判断是公平锁还是非公平锁
public final boolean isFair() {
return sync instanceof FairSync;
}
……………………
可以看出ReentrantLock方法均调用sync的相关方法,故其实际是Sync锁的一个包装类
4.内部类
1.abstract static class Sync extends AbstractQueuedSynchronizer
ReentrantLock实现锁机制的最重要的内部类,继承自AQS类。
tryAcquire、tryRelease和isHeldExclusively方法,继承AbstractQueueSynchronizer类
1.1 tryAcquire方法
在Sync类中为实现tryAcquire方法,因为是由Sync的子类来实现
1.2 tryRelease方法,在释放时,不会考虑锁的顺序问题,故在Sync中实现
//由于是可重入锁,故每释放一次锁,就将state减1。
protected final boolean tryRelease(int releases) {
int c = getState() - releases;
//若当前的线程与要释放锁的线程不一致,则抛出IllegalMonitorStateException(非法监视器状态异常)
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
//若是该线程最后一次持有锁,则通知AQS不再记录当前持有锁的线程
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
setState(c);
return free; //释放成功返回true
}
1.3 isHeldExclusively方法,判断当前持有锁的线程是否等于当前监听的线程
protected final boolean isHeldExclusively() {
return getExclusiveOwnerThread() == Thread.currentThread();
}
1.4 getHoldCount方法,获取独占状态,如果当前线程是独占锁的线程,则返回当前标志位,否则返回0
final int getHoldCount() {
return isHeldExclusively() ? getState() : 0;
}
1.5 getOwner方法,根据当前标识位返回线程,若为0则返回null,否则返回当前独占锁的线程
final Thread getOwner() {
return getState() == 0 ? null : getExclusiveOwnerThread();
}
1.6 newCondition方法,应用于Condition条件时
final ConditionObject newCondition() {
return new ConditionObject();
}
1.7 isLocked方法,表示当前是否被锁住
final boolean isLocked() {
return getState() != 0;
}
1.8 readObject(ObjectInputStream)方法,用于序列化
1.9 nonfairTryAcquire(int)方法,Sync的子类均会调用的一个方法,表示将当前线程加锁标志或可重入标识,是实现加锁功能的主要方法
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) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
2.NonfairSync类,继承自Sync类,实现非公平锁
//tryAcquire方法,重写AQS中的tryAcquire方法,调用Sync中的nonfairTryAcquire方法,将当前线程加锁
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
//lock方法,可以实现抢占式的占有锁。首先通过CAS操作,将标识位设为1。
//成功就将当前线程设置为独占锁的线程并返回,不成功再重新再sync队列中排队
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
3.FairSync类,继承自Sync类,实现公平锁
//只在sync队列中排队
final void lock() {
acquire(1);
}
//tryAcquire方法,重写AQS中的tryAcquire方法,调用Sync中的nonfairTryAcquire方法,将当前线程加锁
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;
}