ReentrantLock 这个Java中重要的锁,我想可能很多人只是听过,并没有使用过,我在看RocketMQ客户端源码的时候发现大量的使用了这个ReentrantLock,从而引起了我的兴趣,下面我们一起从源码的角度来学习ReentrantLock。
我们先来看一下ReentrantLock的继承关系
在正式学习源码之前,我们先来了解几个锁相关的理论
我们由内而外的来剖析这个 ReentrantLock,先来看看它内在的 儿子(Sync)、和孙子(NonFairSync、FairSync)
// 1.继承了 AbstractQueuedSynchronizer
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;
// 定义了一个抽象方法 lock,有子类去具体实现
abstract void lock();
// 非公平尝试获得锁实现
final boolean nonfairTryAcquire(int acquires) { // ... }
// 释放锁
protected final boolean tryRelease(int releases) { // ...}
// 判断当前锁持有者是不是自己
protected final boolean isHeldExclusively() {
return getExclusiveOwnerThread() == Thread.currentThread();
}
// 创建一个条件
final ConditionObject newCondition() {
return new ConditionObject();
}
// 获取当前持有锁的线程
final Thread getOwner() {
return getState() == 0 ? null : getExclusiveOwnerThread();
}
// ReentrantLock 是可重入锁,获取当前加锁的次数
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
}
}
上面有2个重要的方法,我在上面给注释了,下面来详细解析这两个方法 nonfairTryAcquire、tryRelease
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;
}
非公平尝试获取锁,它是被 final修饰,所以不能被重写,但是可以被子类使用。
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;
}
它是被 protected final 修饰的方法,也就是不可以被重写,而且只能自己和子类使用。
它的逻辑也很简单,如果当前操作线程和持有锁的不是同一个就抛出异常,如果减完之后加锁标识为 0,就说明已经彻底释放了,就把当前持有锁的线程设置为 null,最后返回释放结果。
不公平锁,一个静态内部类,它里面就2个方法
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))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
acquireQueued
selfInterrupt
公平锁,一个静态内部类,它里面就2个方法
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
final void lock() {
acquire(1);
}
/**
* Fair version of tryAcquire. Don't grant access unless
* recursive call or no waiters or is first.
*/
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 本身。
这两个参数就没什么好说了的
private static final long serialVersionUID = 7373984872572414699L;
private final Sync sync;
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
直接调用 sync 的lock方法,公平锁和非公平锁都有自己的实现
public void lock() {
sync.lock();
}
获取锁,如果当前线程中断就抛出异常
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
public final void acquireInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (!tryAcquire(arg))
doAcquireInterruptibly(arg);
}
以非公平的方式获取锁
public boolean tryLock() {
return sync.nonfairTryAcquire(1);
}
根据当前锁的类型(公平 or 非公平),来获取锁,并设置超时时间
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
释放锁
public void unlock() {
sync.release(1);
}
创建一个条件
public Condition newCondition() {
return sync.newCondition();
}
获取当前可重入锁的加锁次数
public int getHoldCount() {
return sync.getHoldCount();
}
final int getHoldCount() {
return isHeldExclusively() ? getState() : 0;
}
判断当前持有锁的对象是不是自己
public boolean isHeldByCurrentThread() {
return sync.isHeldExclusively();
}
protected final boolean isHeldExclusively() {
return getExclusiveOwnerThread() == Thread.currentThread();
}
看当前锁,是否已经被持有了
public boolean isLocked() {
return sync.isLocked();
}
final boolean isLocked() {
return getState() != 0;
}
判断当前锁是否是公平锁
public final boolean isFair() {
return sync instanceof FairSync;
}
获取当前持有锁的线程
protected Thread getOwner() {
return sync.getOwner();
}
判断当前是否有等待锁的
public final boolean hasQueuedThreads() {
return sync.hasQueuedThreads();
}
// AbstractQueuedSynchronizer 的方法
public final boolean hasQueuedThreads() {
return head != tail;
}
获取等待锁的长度
public final int getQueueLength() {
return sync.getQueueLength();
}
// AbstractQueuedSynchronizer 的方法
public final int getQueueLength() {
int n = 0;
for (Node p = tail; p != null; p = p.prev) {
if (p.thread != null)
++n;
}
return n;
}
获取正在等待锁的线程
protected Collection<Thread> getQueuedThreads() {
return sync.getQueuedThreads();
}
// AbstractQueuedSynchronizer 的方法
public final Collection<Thread> getQueuedThreads() {
ArrayList<Thread> list = new ArrayList<Thread>();
for (Node p = tail; p != null; p = p.prev) {
Thread t = p.thread;
if (t != null)
list.add(t);
}
return list;
}
是否有等待某种添加的锁
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() + "]");
}