ReentrantLock
- 实现Lock接口,Lock接口只是定义了一些加锁,解锁的一些抽象方法
- 有一个静态的抽象类Sync,继承AQS,
- 静态内部类FairSync、NoFairSync 继承Sync , 默认为非公平锁
使用比较简单,如下面一样,作为一名有追求的程序员,肯定不能局限于表面,继续研究底层源码
public void testLock() {
ReentrantLock lock = new ReentrantLock();
lock.lock();
try {
// 处理业务逻辑
} finally {
lock.unlock();
}
}
ReentrantLock 顾名思义,可重入锁,支持公平,非公平锁
, 而Synchronized只支持非公平锁,通常来说非公平锁的性能要高于公平锁,因为在公平锁下,之前的线程运行时间很长而导致后来的线程始终得不到执行,非公平锁类似于抢占式,不管同步队列是否有线程,先尝试获取锁看下,如果获取成功就直接执行,没有获取成功就放入同步队列中
Sync
使用AQS的state来代表持有锁的数量
// 非公平获取锁
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;
}
protected final boolean tryRelease(int releases) {
// 释放锁资源
int c = getState() - releases;
// 非持有锁的线程调用了tryRelease,抛出异常
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
// 锁是否被线程持有
boolean free = false;
if (c == 0) {
// 没有线程持有锁
free = true;
setExclusiveOwnerThread(null);
}
setState(c);
return free;
}
// 锁是否被当前线程独占
protected final boolean isHeldExclusively() {
return getExclusiveOwnerThread() == Thread.currentThread();
}
非公平锁
ReentrantLock默认为非公平
static final class NonfairSync extends Sync {
final void lock() {
// 首先使用CAS尝试修改状态,成功则设置当前线程为独占
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
// 修改失败,进行重试,重试失败,入队,继续重试,这里调用父类AQS的方法
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
公平锁
static final class FairSync extends Sync {
final void lock() {
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
// hasQueuedPredecessors: 当前节点是否需要排队
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;
}
}
//当前节点是否需要排队 条件有点多,参考https://blog.csdn.net/weixin_38106322/article/details/107154961
public final boolean hasQueuedPredecessors() {
Node t = tail; // Read fields in reverse initialization order
Node h = head;
Node s;
return h != t &&
((s = h.next) == null || s.thread != Thread.currentThread());
}
大致流程如下: