AQS源码浅析(7)——独占模式ReentrantLock
2022-04-08 本文已影响0人
墨_0b54
ReentrantLock的基本语义与synchronized相同,但相对synchronized更加灵活。
ReentrantLock有两种模式:公平模式和非公平模式。
ReentrantLock加锁的实现
公平模式下,如果有线程正在等待,则不参与竞争,对AQS的tryAcquire实现如下:
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) //溢出了,最大可重入是int的最大值
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
非公平模式下,直接参与竞争,对AQS的tryAcquire实现如下:
final void lock() {//非公平,直接竞争一次
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
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;
}
ReentrantLock对解锁实现
先看一下ReentrantLock的基本实现,我们仅看解锁相关方法,实现很简单易懂
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;
}