先上源码
public class ReentrantLock implements Lock, java.io.Serializable {
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();
}
// 获取锁
public void lock() {
sync.lock();
}
// 可中断的获取锁
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
// 尝试获取锁,成功返回true,失败返回false
public boolean tryLock() {
return sync.nonfairTryAcquire(1);
}
// 带超时时间的尝试获取锁,成功返回true,失败返回false
public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
// 释放锁
public void unlock() {
sync.release(1);
}
// 返回一个Condition对象
public Condition newCondition() {
return sync.newCondition();
}
// 获取当前线程持有锁的个数
public int getHoldCount() {
return sync.getHoldCount();
}
// 判断当前线程是否持有锁
public boolean isHeldByCurrentThread() {
return sync.isHeldExclusively();
}
// 判断锁是否被任意线程持有
public boolean isLocked() {
return sync.isLocked();
}
// 获取同步器
public final Sync getSync() {
return sync;
}
// 抽象同步器
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;
// 加锁
abstract void lock();
// 尝试非公平获取锁
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 void acquireInterruptibly(int arg) throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (!tryAcquire(arg))
doAcquireInterruptibly(arg);
}
// 尝试获取锁,可响应中断和超时
final boolean tryAcquireNanos(int arg, long nanosTimeout) throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
return tryAcquire(arg) || doAcquireNanos(arg, nanosTimeout);
}
// 释放锁
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;
}
// 是否独占锁
final boolean isHeldExclusively() {
return getExclusiveOwnerThread() == Thread.currentThread();
}
// 条件变量
final ConditionObject newCondition() {
return new ConditionObject();
}
// 获取当前线程持有锁的个数
final int getHoldCount() {
return isHeldExclusively() ? getState() : 0;
}
// 非公平锁同步器
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
// 加锁
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
// 尝试获取锁
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
// 公平锁同步器
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
// 加锁
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;
}
}
}
}
ReentrantLock 是 Java 中的一个可重入锁,它提供了与 synchronized 相同的互斥性和内存可见性,但是它比 synchronized 更加灵活,可以实现更多高级的功能,如公平锁、可中断锁、多条件变量等。
下面是 ReentrantLock 的源码分析总结:
ReentrantLock 是一个可重入锁,它通过一个 int 类型的 state 变量来表示锁的状态,其中高 16 位表示持有锁的线程的数量,低 16 位表示当前线程重入的次数。
ReentrantLock 支持公平锁和非公平锁,默认情况下是非公平锁。公平锁会按照线程请求锁的顺序来获取锁,而非公平锁则会优先考虑已经在等待队列中的线程,从而可能导致新的线程插队获取锁。
ReentrantLock 支持可中断锁,即在等待锁的过程中可以响应中断信号,通过调用 lockInterruptibly() 方法来实现。
ReentrantLock 支持多条件变量,通过 Condition 接口来实现。每个 ReentrantLock 对象都可以创建多个 Condition 对象,用于实现不同的等待/通知机制。
ReentrantLock 内部使用了 AQS(AbstractQueuedSynchronizer)来实现锁的同步机制。AQS 是一个抽象类,它提供了一些基本的同步操作,如获取锁、释放锁、等待队列等,ReentrantLock 利用 AQS 的模板方法来实现自己的同步逻辑。
ReentrantLock 的 lock() 方法和 unlock() 方法是 ReentrantLock 的核心方法,它们通过调用 AQS 的 acquire() 和 release() 方法来实现锁的获取和释放。在 lock() 方法中,如果当前线程已经持有锁,则直接增加重入次数;否则,通过 AQS 的 acquire() 方法来获取锁。在 unlock() 方法中,如果当前线程还持有锁,则减少重入次数;否则,通过 AQS 的 release() 方法来释放锁。
ReentrantLock 的 tryLock() 方法是一个非阻塞的尝试获取锁的方法,它会立即返回获取锁的结果,而不会阻塞当前线程。如果获取锁成功,则返回 true;否则,返回 false。
ReentrantLock 的 tryLock(long timeout, TimeUnit unit) 方法是一个带超时时间的尝试获取锁的方法,它会在指定的时间内尝试获取锁,如果获取锁成功,则返回 true;否则,返回 false。
ReentrantLock 的 lockInterruptibly() 方法是一个可中断的获取锁的方法,它会在等待锁的过程中响应中断信号,如果当前线程被中断,则抛出 InterruptedException 异常。
ReentrantLock 的 Condition 接口提供了等待/通知机制,它可以让线程在等待某个条件成立时进入等待状态,并在条件成立时被唤醒。Condition 接口的实现类是 ConditionObject,它是 AQS 的内部类,用于实现等待队列的管理和线程的唤醒。
总结,ReentrantLock 是一个非常强大和灵活的锁,它提供了很多高级的功能,可以满足不同的同步需求。但是,由于它的实现比较复杂,使用时需要注意一些细节,避免出现死锁、饥饿等问题。